yamada-hakase’s blog

LinuxなどのOSSやクラウドについて

SELinuxとFirewallを有効にしたまま443でsshを受けるように設定する

1. はじめに

443ポートを使ってssh接続したいことがある。クライアント側はPuTTy/Tera Term/opensshでポート変更するだけでよいが、サーバ側は少し手順が複雑になる。少なくともGUIツール上でポート番号を変えるだけと言うことはない。

また今どきのLinuxは、SELinuxFirewall(ここではfirewalldやiptablesなどのソフトウェア実装を指している)がデフォルトで有効になっている。

SELinuxFirewallを有効にするかどうかは別の議論として、有効にして難易度が高くなったときの手段を知っていて損は無いだろう。そこで今回は共に有効にしたまま設定する方法を説明する。

なおSELinuxFirewallを有効にするかべきかについては、別エントリに書いた。

1-1. 利用環境

当然同じRHELディストリビューションでも同じハズである。

1-2. 設定手順

設定する手順は以下の通り。6系と7系で操作が異なるところは別に書いている。

  1. SELinuxを設定する
  2. Firewallを設定する
  3. sshdを設定する

2. SELinuxを設定する

参考資料

2-1. SELinuxが有効化されているか確認する

現在のステータスを確認するとEnforcingなのでSELinuxは有効になっている。無効のときはPermissiveもしくはDisabledだ。

# getenforce
Enforcing

こちらのコマンドを使うと、もっと細かい情報を表示できる。

# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      31

当然設定ファイルの内容もenforcingになっている。

$ grep ^SELINUX= /etc/selinux/config
SELINUX=enforcing

ヒント SELinuxのモードを永続的に変更するにはOSを再起動する必要がある。しかしsetenforce 0を使うと、動的にpermissiveモードに変更できる。ベアメタルサーバなどOSの再起動に時間のかかるときには便利だ。ただし永続的に変更するには設定ファイル/etc/selinux/configも変更する必要がある。

2-2. SELinuxのポート設定を確認する

SELinuxで443ポートがどのように設定されているか確認する。http_port_tになっているので、Webサーバ(httpd)用に設定されている。

# semanage port -l | grep 443
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000★
pki_ca_port_t                  tcp      829, 9180, 9701, 9443-9447
pki_kra_port_t                 tcp      10180, 10701, 10443-10446
pki_ocsp_port_t                tcp      11180, 11701, 11443-11446
pki_tks_port_t                 tcp      13180, 13701, 13443-13446

2-3. 443ポートをsshd用に変更する

443ポートをsshd用に変更する。

# semanage port -m -t ssh_port_t -p tcp 443

確認するとsshd用に設定が変更されている。

# semanage port -l | grep 443

http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
pki_ca_port_t                  tcp      829, 9180, 9701, 9443-9447
pki_kra_port_t                 tcp      10180, 10701, 10443-10446
pki_ocsp_port_t                tcp      11180, 11701, 11443-11446
pki_tks_port_t                 tcp      13180, 13701, 13443-13446
ssh_port_t                     tcp      443, 22 ★追加された

次にFirewallの設定をする。

3. Firewallを設定する

CentOS 6とCentOS 7/8では、Firewallの設定方法がまったく違うので、それぞれ説明する。

参考資料:

3-1. CentOS 7 / 8(firewalld)の場合

firewalldの設定を確認する

firewalldが起動していることを確認する。activeなので有効化されている。

# systemctl is-active firewalld
active

設定を確認すると、いくつかのポートが開いていることがわかる。しかしhttps/443は開いていない。

# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens3
  sources:
  services: ssh dhcpv6-client ★
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

firewalldの443ポートを開ける

開いていないので443ポートを開ける。ここでは--add-port=443/tcpでポートを開けている。--add-service=httpsでも結果は同じだが、httpsだと気持ち悪いので、このようにした。

# firewall-cmd --add-port=443/tcp  --permanent --zone=public

リロードして設定を有効化する。

# firewall-cmd --reload
success

再び設定を確認すると443ポートが空いていることがわかる。次はsshdの設定だ。

# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens3
  sources:
  services: ssh dhcpv6-client
  ports: 443/tcp ★これ
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

3-2. CentOS 6(iptables)の場合

iptablesの設定を確認する

iptablesが起動していることを確認する。このようにズラッと表示されれば起動している。

# service iptables status
テーブル: filter
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED
2    ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0
★以下省略

iptablesの設定を確認する。重要なINPUTチェーンだけを表示すると、icmpと22ポートだけが開いていて、443ポートは開いていない。

# iptables -L INPUT --line-number
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
2    ACCEPT     icmp --  anywhere             anywhere
3    ACCEPT     all  --  anywhere             anywhere
4    ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh
5    REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited
★以下省略

iptablesの443ポートを開ける

開いていないので443ポートを開ける。

# iptables -I INPUT 5 -p tcp --dport 443 -j ACCEPT

再び設定を確認すると、INPUTチェーンの最後から2行目に設定が追加され、https/443ポートが開いていることがわかる。

# iptables -L INPUT --line-number
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
2    ACCEPT     icmp --  anywhere             anywhere
3    ACCEPT     all  --  anywhere             anywhere
4    ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh
5    ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:https★
6    REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited

変更内容を保存する。すると設定は/etc/sysconfig/iptablesに保存される。以上でiptablesは終了である。

# service iptables save

4. sshdを設定する

4-1. sshdのリスニングポートを追加する

デフォルトでは22ポートをリスニングしているので、443ポートも追加する。その前に設定ファイルをバックアップする。

# cp -f /etc/ssh/sshd_config /etc/ssh/sshd_config-`date +%Y%m%d`
# sed -i -e "s/\#*Port 22/Port 22\nPort 443/" /etc/ssh/sshd_config

次のように表示されれば、リスニングポートとして22と443が設定されている。

# grep ^Port /etc/ssh/sshd_config
Port 22
Port 443

4-2. sshdを再起動して有効化する

sshdを再起動して設定を有効化する。

# systemctl restart sshd
# service sshd restart

以上で設定はすべて終了した。実際にsshクライアントから接続できるか確認して欲しい。

5. まとめバージョン

コピペで一括実行できるように、まとめバージョンも紹介する。

CentOS 7 / CentOS 8

# 443/tcpをssh用に変更
semanage port -m -t ssh_port_t -p tcp 443

# 443ポートを開放
firewall-cmd --add-port=443/tcp  --permanent --zone=public

# firewalldの設定を有効化
firewall-cmd --reload

# sshdのリスニングポートに443を追加。元ファイルは.bakを付けてバックアップ
sed -i".bak" -e "s/\#*Port 22/Port 22\nPort 443/" /etc/ssh/sshd_config

# sshdを再起動して443ポートを有効化
systemctl restart sshd

CentOS 6

# 443/tcpをssh用に変更
semanage port -m -t ssh_port_t -p tcp 443

# 443ポートを開放
iptables -I INPUT 5 -p tcp -m state --state NEW --dport 443 -j ACCEPT

# iptablesの設定を保存
service iptables save

# sshdのリスニングポートに443を追加。元ファイルは.bakを付けてバックアップ
sed -i".bak" -e "s/\#*Port 22/Port 22\nPort 443/" /etc/ssh/sshd_config

# sshdを再起動して443ポートを有効化
service sshd restart