[SSH][CentOS7] 特定のユーザーを固定IPアドレスからのみ接続許可する


複数の接続元からSSH接続をさせたい、かつそのうち1つのユーザーは動的IPアドレスから接続させなければならない、という要件はよくある話です。こうしたユーザーのためにSSHで使用するTCP/22番ポートをフルオープンにするのは躊躇われるかと思いますので、こんな仕組みを考えてみました。

  • ユーザー「hamada」は固定IPアドレスからTCP/22へssh接続させる
  • ユーザー「nullpopopo」は動的IPアドレスからTCP/12345へssh接続させる

下記手順を行う前に、あらかじめ hamada ユーザーと nullpopopo ユーザーを useradd コマンドで作成しておいてください。

Ansible徹底入門 クラウド時代の新しい構成管理の実現

■ sshd_config 設定変更

まず、 /etc/ssh/sshd_config で 22番ポートのほかに12345番ポートでsshdを待ち受けるようにします。

before # Port 22
after Port 22
Port 12345

さらに、 /etc/ssh/sshd_config の末尾に以下を追記します。

AllowUsers !*
Match LocalPort 22
    AllowUsers hamada
Match LocalPort 12345
    AllowUsers nullpopopo

上記例の1行目、 AllowUsers ですべてのユーザーのログインを拒否し、続いて LocalPort が 22 の場合、 hamada ユーザーのみを許可し、 LocalPort が 12345 の場合、 nullpopopo ユーザーを許可します。ついでを言えば、 hamada ユーザーが外出先からSSH接続したい、という場合は「AllowUsers nullpopopo」を「AllowUsers nullpopopo hamada」とすればOKです。

ここまで終わったら以下のコマンドで sshd を再起動します。

$ sudo systemctl restart sshd

sshd の待受ポートがちゃんとListenしているかを確認しましょう。

$ ss -lnt
State       Recv-Q Send-Q                    Local Address:Port                                   Peer Address:Port              
LISTEN      0      128                                   *:22                                                *:*                  
LISTEN      0      128                                   *:12345                                             *:*                  
LISTEN      0      100                           127.0.0.1:25                                                *:*                  
LISTEN      0      128                                  :::22                                               :::*                  
LISTEN      0      128                                  :::12345                                            :::*                  
LISTEN      0      100                                 ::1:25                                               :::*                  

また、22番ポートと12345番ポートをbindしているコマンドがsshdであることもあわせて確認しましょう。

$ sudo lsof -i:22
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    2086 root    5u  IPv4  24138      0t0  TCP *:ssh (LISTEN)
sshd    2086 root    6u  IPv6  24140      0t0  TCP *:ssh (LISTEN)
$ sudo lsof -i:12345
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    2086 root    3u  IPv4  24134      0t0  TCP *:12345 (LISTEN)
sshd    2086 root    4u  IPv6  24136      0t0  TCP *:12345 (LISTEN)

lsofコマンドがインストールされていない場合は、yumコマンドでlsofパッケージをインストールしてください。


■ iptables設定

まず、今のゾーン設定を確認します。

$ sudo firewall-cmd --get-default-zone
public
$ sudo firewall-cmd --get-active-zones
public
  interfaces: eth0 eth1

続いて、 public ゾーンの設定を確認します。

$ sudo firewall-cmd --info-zone=public
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1
  sources: 
  services: dhcpv6-client ssh
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  sourceports: 
  icmp-blocks: 
  rich rules: 

services で ssh を許可しているので、これを取り消しつつ固定IPアドレスから ssh を許可し、さらに TCP/12345 を許可します。TCP12345番ポートはWell-Knownではないので、ポート番号指定で穴をあけてあげましょう。以下例は TCP/22 の接続元IPアドレス 192.168.0.100を許可します。

$ sudo firewall-cmd --permanent --remove-service=ssh
$ sudo firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.0.100/32" port protocol="tcp" port="22" accept"
$ sudo firewall-cmd --permanent --add-port=12345/tcp
$ sudo firewall-cmd --reload

ここまで終わったら再度 public ゾーンの設定を確認しましょう。

$ sudo firewall-cmd --info-zone=public
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1
  sources: 
  services: dhcpv6-client
  ports: 12345/tcp
  protocols: 
  masquerade: no
  forward-ports: 
  sourceports: 
  icmp-blocks: 
  rich rules: 
        rule family="ipv4" source address="192.168.0.100/32" port port="22" protocol="tcp" accept

以上で設定終了です。接続確認を行う場合、fail2ban に引っかからないよう、引っかかってしまった場合はすぐにban解除できるようにして確認しましょう。でわー。