OpenSSHのセキュリティ/設定するべき20のこと




投稿日:

この記事は、為になったと思った以下の記事の勝手な日本語訳です。
http://www.cyberciti.biz/tips/linux-unix-bsd-openssh-server-best-practices.html

OpenSSHは SSHプロトコルを実装したもので、リモートログインやバッックアップ作成、SCPやSFTPを利用したリモートのファイル転送などで使うことがよくあります。
そして、SSHは2つの異なるネットワークやシステム間でのデータ転送においてデータの機密性・安全性を守るにはパーフェクトな仕組みを持っています。
その一番の利点は共有鍵暗号によるサーバ認証です。
OpenSSHの新セキュリティホールに関する噂もありますが、それは噂。OpenSSHサーバのセキュリティを強固にするには、ほんの少しの微調整をするだけです。

■ 設定ファイルとSSHポートのおさらい


/etc/ssh/sshd_config - OpenSSH server 設定ファイル
/etc/ssh/ssh_config - OpenSSH クライアント設定ファイル
~/.ssh/ - ユーザのSSH設定ディレクトリ
~/.ssh/authorized_keys 又は ~/.ssh/authorized_keys - ユーザアカウントにログインするための共通鍵リスト (RSA or DSA) 
/etc/nologin - このファイルがある場合には、rootユーザ以外のログインを拒否します。
/etc/hosts.allow と /etc/hosts.deny : アクセスコントロールをするリスト。tcp-wrappersによる制御の定義を記載します。
SSH のデフォルトポート : TCP 22



#1: OpenSSH Serverの無効化(ローカルマシンにて)


デスクトップ・ラップトップパソコンは、OpenSSHサーバなしでも動きます。
そのパソコンへのリモートログインやSSHを利用したデータ転送などをしないのであれば、SSHサーバを無効にして削除しましょう。

CentOS / RHEL / Fedora Linuxユーザは、コマンドでopenssh-serverの無効化・削除が可能です。
# chkconfig sshd off
# yum erase openssh-server

Debian / Ubuntu Linuxユーザは apt-getコマンドで無効化・削除が可能です。
# apt-get remove openssh-server

sshの例外ルールを削除するため、iptablesのアップデートは必要かも知れません。
CentOS / RHEL / Fedora では /etc/sysconfig/iptables と /etc/sysconfig/ip6tablesを編集します。
そして、iptablesを再起動します。

# service iptables restart
# service ip6tables restart



#2: SSH Protocol 2 のみを使用する。


SSH-1 には中間者攻撃の問題があり、セキュリティの脆弱性を抱えています。既に廃れた技術であり、どんなことがあっても使用すべきでありません。
設定ファイルには、以下の一行を追加しましょう。

Protocol 2



#3: SSHアクセスをできるユーザを制限する。


全てのユーザアカウントが、パスワードや公開鍵を使ったSSHでログインすることは難しいです。たまには、ftpやメール用としてUNIXやLinuxにユーザアカウントを作る事もあるでしょう。
しかもそのユーザアカウントはSSHを使ってシステムにログインできるのです。
そして、コンパイラやスクリプ言語等のシステムツールにフルアクセス出来てしまいます。これでネットワークポートを空けたり、トリッキーなことが数多く可能になります。


AllowUsersにユーザを記載しなければ、自分のクライアントの1人に超時代遅れのphpスクリプトをそのままにしているユーザがいる危ない状態でもアタッカーはSSH経由でシステムに入ることが出来ません。
なぜなら、AllowUsersに記載されていないからです。phpスクリプトを利用してシステムに新しいアカウントを追加できる能力があっても入れなければ意味がありません。


以下のように設定します。
SSH経由では、root, home, fuga ユーザのみを許可する設定をsshd_configに記載します。

AllowUsers root home fuga

反対に全てのユーザを許可し、数ユーザのみを拒否する場合は、以下のように記載します。

DenyUsers saroj anjali foo

Linux PAMでも、同様にsshdサーバ経由の許可・拒否の設定が可能です。グループリストとして許可・拒否の登録も可能です。


#4: アイドルタイムアウトインターバルの設定。


セッションが無応答状態になりログアウトするのを避けるため、アイドルタイムアウトインターバルの設定をすることが出来ます。
よく「Write failed: Broken pipe 」という表示でログアウトしてしまっています。


Open sshd設定を以下のようにします。

ClientAliveInterval 300
ClientAliveCountMax 0



アイドルタイムアウトインターバルを300秒=5分で設定しています。この時間をすぎるとアイドル状態(無応答状態)のユーザは自動でログアウトさせられます。
詳細については、BASH / TCSH / SSH ユーザ の自動ログアウトの仕組みから学びましょう。


#5: .rhosts ファイルの無視。


ユーザの「 ~/.rhosts 」と「 ~/.shosts」ファイルは読んではいけません。無視しましょう。sshd_configファイルを以下のように設定しましょう。

IgnoreRhosts yes

これにより、時代遅れなrshコマンドの動作をエミュレート可能になり、RSH経由の安全でないアクセスを無効化します。


#6: Hostbased認証を無効にする。


Hostbased認証を無効にするために、sshd_configファイルを以下のように設定しましょう。

HostbasedAuthentication no



#7: SSHでのrootログインを無効にする。


ネットワーク越しにrootユーザがsshで接続する必要はない。
通常のユーザは、root権限になるために、su やsudo(こちら推奨)を使う事ができる。
これは同時に、誰がsudoを使って権限のついたコマンドを実施したかを確実に把握することができる。
rootでのsshログインを無効にするために、 sshd_configを以下のように編集しアップデートしよう。

PermitRootLogin no



#8: 接続時の警告メッセージを有効にする


sshd_configを以下のようにアップデートして有効にする。

Banner /etc/issue

/etc/issueファイルは、テキストを記入すればよい。
元リンクのサイトだと以下のようなテキストを入れている。


以下原文
———————————————————————————————-
You are accessing a XYZ Government (XYZG) Information System (IS) that is provided for authorized use only.
By using this IS (which includes any device attached to this IS), you consent to the following conditions:
+ The XYZG routinely intercepts and monitors communications on this IS for purposes including, but not limited to,
penetration testing, COMSEC monitoring, network operations and defense, personnel misconduct (PM),
law enforcement (LE), and counterintelligence (CI) investigations.
+ At any time, the XYZG may inspect and seize data stored on this IS.
+ Communications using, or data stored on, this IS are not private, are subject to routine monitoring,
interception, and search, and may be disclosed or used for any XYZG authorized purpose.
+ This IS includes security measures (e.g., authentication and access controls) to protect XYZG interests–not
for your personal benefit or privacy.
+ Notwithstanding the above, using this IS does not constitute consent to PM, LE or CI investigative searching
or monitoring of the content of privileged communications, or work product, related to personal representation
or services by attorneys, psychotherapists, or clergy, and their assistants. Such communications and work
product are private and confidential. See User Agreement for details.
———————————————————————————————-


#8: sshのポート22番をFirewallで守ろう


iptablesやパケットフィルタFW設定によって、sshポートである22番は閉じるようにする必要がある。
通常は、OpenSSHサーバはLANかリモートのWAN環境からしかコネクション確立はしないようにすべき。


Netfilter(iptables)の設定


192.168.1.0/24 と 202.54.1.5/29からしかsshを受け付けないようにする場合、/etc/sysconfig/iptables (Redhat系の場合)

-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -s 202.54.1.5/29 -m state --state NEW -p tcp --dport 22 -j ACCEPT

IPv6設定も入れるのであれば、以下のようにする。

 -A RH-Firewall-1-INPUT -s ipv6network::/ipv6mask -m tcp -p tcp --dport 22 -j ACCEPT

Replace ipv6network::/ipv6mask with actual IPv6 ranges.



#9: SSHポートの変更とIPを絞ること。


SSHポート通信可能なインターフェイスとIPアドレスを絞ることで、SSHの待ち受けポートを変更する。これにより馬鹿なスクリプト被害は防ぐことができる。

192.168.1.5 と 202.54.1.5からport300に接続するような設定の場合は以下にようになります。

Port 300
ListenAddress 192.168.1.5
ListenAddress 202.54.1.5
A better approach to use proactive approaches scripts such as fail2ban or denyhosts (see below).



#10: 強力なSSHパスワードとパスフレーズを使用する。 


強力なSSHパスワードや鍵のパスフレーズを使用することはとっても大切です。
辞書にありそうなパスワードだと総当たり攻撃を受けやられてしまいます。
辞書攻撃に弱いパスワードを避けるように、また、弱いパスワードを見つけ出すツールを使うように強制も出来ます。
これは、シンプルなパスワードジェネレータのサンプルです。 ~/.bashrcに置いて下さい。

genpasswd() {
	local l=$1
       	[ "$l" == "" ] && l=20
      	tr -dc A-Za-z0-9_ < /dev/urandom | head -c ${l} | xargs
}
Run it:


genpasswd 16

Output:
uw8CnDVMwC6vOKgW



#11: 共通鍵認証を使う 


秘密鍵のパスワード保護に、共通鍵・秘密鍵のペアキーを使います。RSAやDSA キー認証の使い方を調べましょう。
絶対にパスフレーズがない鍵をログインに使用してはいけません。


#12: キーチェーン認証を使う


キーチェーンはとっても便利でフレキシブルなキーベース認証をデザインするためのあるbashスクリプトがあります。
パスフレーズなしの鍵に様々なセキュリティ的メリットをつけることができます。



#13: Chroot SSHD


chrootはこちら
http://itpro.nikkeibp.co.jp/article/Keyword/20101204/354862/

デフォルトのユーザは、/etc/,/binのようなサーバのディレクトリを参照できます。chrootやrsshのようなツールを使用することでssh接続のセキュリティを高める事ができます。
OpenSSH 4.8p1 か 4.9p1では、サードパーティのrsshのようなツールの利用や、複雑なchroot設定することなしにサーバのルートディレクトリなどにロックをかける事が可能です。こちらのブログ記事を見て下さい。詳しく書いています。


#14: TCP Wrapperを使用する


TCP WrapperはホストベースのACLネットワークシステムです。インターネットへのアクセスをフィルターします。
OpenSSHはTCP Wrapperをサポートしています。
192.168.1.2 172.16.23.12からのみのsshを許可する時は、/etc/hosts.allowに以下のように記載します。

sshd : 192.168.1.2 172.16.23.12 



#15: 空のパスワードを無効にする


空のパスワードユーザのリモートログインは許可していはいけない。sshd_configに以下を追記しましょう。

PermitEmptyPasswords no



#16: SSH クラッカー(総当たり攻撃)を邪魔する 


総当たりは、単一・分散系のコンピュータネットワークを使って、大量のリクエストを送りつける、暗号スキームを打ち負かす攻撃方法です。
SSHの総当たり攻撃を防ぐには、以下のソフトを使ってみましょう。

以下原文

DenyHosts is a Python based security tool for SSH servers. It is intended to prevent brute force attacks on SSH servers by monitoring invalid login attempts in the authentication log and blocking the originating IP addresses.
Explains how to setup DenyHosts under RHEL / Fedora and CentOS Linux.
Fail2ban is a similar program that prevents brute force attacks against SSH.
security/sshguard-pf protect hosts from brute force attacks against ssh and other services using pf.
security/sshguard-ipfw protect hosts from brute force attacks against ssh and other services using ipfw.
security/sshguard-ipfilter protect hosts from brute force attacks against ssh and other services using ipfilter.
security/sshblock block abusive SSH login attempts.
security/sshit checks for SSH/FTP bruteforce and blocks given IPs.
BlockHosts Automatic blocking of abusive IP hosts.
Blacklist Get rid of those bruteforce attempts.
Brute Force Detection A modular shell script for parsing application logs and checking for authentication failures. It does this using a rules system where application specific options are stored including regular expressions for each unique auth format.
IPQ BDB filter May be considered as a fail2ban lite.



#17: ポート22を Rate-limit Incoming にしよう。


iptablesでは、ポート22に接続に来るアクセスにフィルタを使用して制限をかける事が可能です。



60秒で5回以上のport22へのssh接続が確認されたら、dropする。

#!/bin/bash
inet_if=eth1
ssh_port=22
$IPT -I INPUT -p tcp --dport ${ssh_port} -i ${inet_if} -m state --state NEW -m recent  --set
$IPT -I INPUT -p tcp --dport ${ssh_port} -i ${inet_if} -m state --state NEW -m recent  --update --seconds 60 --hitcount 5 -j DROP

iptablesスクリプトで上のスクリプトを呼びましょう。違うオプションは、以下です。

$IPT -A INPUT  -i ${inet_if} -p tcp --dport ${ssh_port} -m state --state NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT
$IPT -A INPUT  -i ${inet_if} -p tcp --dport ${ssh_port} -m state --state ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o ${inet_if} -p tcp --sport ${ssh_port} -m state --state ESTABLISHED -j ACCEPT
# another one line example
# $IPT -A INPUT -i ${inet_if} -m state --state NEW,ESTABLISHED,RELATED -p tcp --dport 22 -m limit --limit 5/minute --limit-burst 5-j ACCEPT

iptablesのmanページをみて見ましょう。

*BSD PF Example

次の設定は、ソース毎に最大で20回の接続、5秒で15回のコネクションが発生した場合の条件です。
これを上回った場合には、abusive_ipsにトラフィックが流れ、接続を遮断します。

sshd_server_ip="202.54.1.5"
table <abusive_ips> persist
block in quick from <abusive_ips>
pass in on $ext_if proto tcp to $sshd_server_ip port ssh flags S/SA keep state (max-src-conn 20, max-src-conn-rate 15/5, overload <abusive_ips> flush)



#18: ポートノッキングを利用する。


ポートノッキングは、直前にある特定のポートに特定の連続した接続があった場合にのみfirewallのportを開けることができるというツールです。
一度正しいものが実施されれば、そのコネクションのホストにのみ接続を許します。以下が例になります。

$IPT -N stage1
$IPT -A stage1 -m recent --remove --name knock
$IPT -A stage1 -p tcp --dport 3456 -m recent --set --name knock2
 
$IPT -N stage2
$IPT -A stage2 -m recent --remove --name knock2
$IPT -A stage2 -p tcp --dport 2345 -m recent --set --name heaven
 
$IPT -N door
$IPT -A door -m recent --rcheck --seconds 5 --name knock2 -j stage2
$IPT -A door -m recent --rcheck --seconds 5 --name knock -j stage1
$IPT -A door -p tcp --dport 1234 -m recent --set --name knock
 
$IPT -A INPUT -m --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -p tcp --dport 22 -m recent --rcheck --seconds 5 --name heaven -j ACCEPT
$IPT -A INPUT -p tcp --syn -j doo

fwnop はポートノッキングとpassive fingerprintingを合わせた実装がされています。



#19: ログアナライザを使う。


logwatch や logcheckでログを読もう。これらのツールはログの解読を助けてくれる。
sshd_configにて、INFO か DEBUG をセットしよう。

LogLevel INFO



#20: OpenSSH and Operating Systems をアップデートする


最新のセキュリティパッチがあたっている yum, apt-get, freebsd-updateなどのツールを使用することを進めます。

他のオプション
opensshのバージョンを隠す為に、ソースコードをアップデートし、コンパイルし直します。以下のものは sshd_config でenabledになっていることを確認しましょう。

#  root権限を分離する。
UsePrivilegeSeparation yes
# ユーザのファイルおよびホームディレクトリの所有権とパーミッションをチェックすべきかどうかを指定します。通常はyes。ChrootDirectoryには適応されません。
StrictModes yes
# 逆引き設定を入れる。
VerifyReverseMapping yes
# ポートフォワード設定は必要ですか?
AllowTcpForwarding no
X11Forwarding no
#  パスワード認証の有無。 デフォルトはyesで、認証を許可する。noは許可しない。
PasswordAuthentication no

restarting / reloadingをする前に、sshd_configファイルを確認しましょう。

# /usr/sbin/sshd -t