踏み台SSHサーバー構築メモ

これは [Media Do Advent Calendar 2019](https://qiita.com/advent-calendar/2019/mediado) の記事です。


# はじめに

2年前に踏み台SSHサーバーを立てたときのメモです。


## SSH 接続方法

Port22222
公開鍵認証のみ

※ Local側IFのみPort22とパスワード認証を許可する





# SSHサーバーをセットアップする

CentOS7で構築
firewalldは殺さず生かしておく


/etc/ssh/sshd_config は以下の通り
listenポート追加
Local側IFのみパスワード認証可


```config:/etc/ssh/sshd_config
Protocol 2
Port 22
Port 22222
SyslogFacility AUTHPRIV
PermitRootLogin no
PasswordAuthentication no
AddressFamily inet
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
UsePAM yes
Subsystem       sftp    /usr/libexec/openssh/sftp-server
UseDNS no

PubkeyAuthentication yes
AuthorizedKeysFile     .ssh/authorized_keys

Match LocalAddress 192.168.***.***
    PasswordAuthentication yes

```

`# systemctl restart sshd`





### firewalldで22222も開ける

`# cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/`

```config:/etc/firewalld/services/ssh.xml

<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>SSH</short>
  <description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description>
  <port protocol="tcp" port="22"/>
  <port protocol="tcp" port="22222"/> (※追加する)
</service>
```


`# firewall-cmd --reload`


※ 今回はこのSSHサーバーの上位にFirewallがあったので、FirewallでPort22222のみ許可した。（Port22はブロック）



### 一応、ユーザークォータを /home で有効にしておく

```config:/etc/fstab
#
# /etc/fstab
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/cl-root     /                       xfs     defaults        0 0
UUID=099a76bd-8b07-4386-ab6d-be892bb8abf2 /boot                   xfs     defaults        0 0
/dev/mapper/cl-home     /home                   xfs     defaults        0 0
/dev/mapper/cl-swap     swap                    swap    defaults        0 0
[root@sshgw01 ~]#

/dev/mapper/cl-home     /home                   xfs     defaults        0 0
↓
/dev/mapper/cl-home     /home                   xfs     defaults,usrquota,gquota        0 0
```

`# mount -o remount /home`

remountではなぜか反映されなかったので再起動・・・


```config:/etc/mtab
/dev/mapper/cl-home /home xfs rw,relatime,attr2,inode64,usrquota,grpquota 0 0
```

```
# xfs_quota -x -c state /home
User quota state on /home (/dev/mapper/cl-home)
  Accounting: ON
  Enforcement: ON
  Inode: #74 (2 blocks, 2 extents)
Group quota state on /home (/dev/mapper/cl-home)
  Accounting: ON
  Enforcement: ON
  Inode: #75 (2 blocks, 2 extents)
Project quota state on /home (/dev/mapper/cl-home)
  Accounting: OFF
  Enforcement: OFF
  Inode: #75 (2 blocks, 2 extents)
Blocks grace time: [7 days]
Inodes grace time: [7 days]
Realtime Blocks grace time: [7 days]
```



# 操作ログを残す（Snoopy Logger利用）

・Snoopy Logger を入れる

```
# wget -O snoopy-install.sh https://github.com/a2o/snoopy/raw/install/doc/install/bin/snoopy-install.sh

# chmod 755 snoopy-install.sh

# ./snoopy-install.sh stable
```

スタートコマンド： snoopy-enable
停止コマンド： snoopy-disable




```config:/var/log/secure
Nov 30 15:12:09 sshgw snoopy[18412]: [uid:1000 sid:18382 tty:/dev/pts/4 cwd:/home/u1ymd filename:/usr/bin/tty]: /usr/bin/tty -s
Nov 30 15:12:09 sshgw snoopy[18413]: [uid:1000 sid:18382 tty:/dev/pts/4 cwd:/home/u1ymd filename:/usr/bin/tput]: /usr/bin/tput colors
Nov 30 15:12:09 sshgw snoopy[18415]: [uid:1000 sid:18382 tty:/dev/pts/4 cwd:/home/u1ymd filename:/usr/bin/dircolors]: /usr/bin/dircolors --sh /etc/DIR_COLORS
Nov 30 15:12:09 sshgw snoopy[18416]: [uid:1000 sid:18382 tty:/dev/pts/4 cwd:/home/u1ymd filename:/usr/bin/grep]: /usr/bin/grep -qi ^COLOR.*none /etc/DIR_COLORS
Nov 30 15:12:09 sshgw snoopy[18418]: [uid:1000 sid:18382 tty:/dev/pts/4 cwd:/home/u1ymd filename:/usr/bin/id]: /usr/bin/id -u
Nov 30 15:12:19 sshgw snoopy[18419]: [uid:1000 sid:18382 tty:/dev/pts/4 cwd:/home/u1ymd filename:/usr/bin/ssh]: ssh hogehoge@10.10.10.**
```

/etc/snoopy.ini でmessage_formatを少し変更
（uidだけじゃぱっと見で誰なのかわからないのでusernameを追加）

```config:/etc/snoopy.ini
message_format = "[uid:%{uid} username:%{username} sid:%{sid} tty:%{tty} cwd:%{cwd} filename:%{filename}]: %{cmdline}"`
```

```config:/var/log/secure
Dec  1 13:22:31 sshgw snoopy[2588]: [uid:1000 username:u1ymd sid:2544 tty:/dev/pts/1 cwd:/home/u1ymd filename:/usr/bin/ls]: ls --color=auto
Dec  1 13:22:39 sshgw snoopy[2591]: [uid:0 username:root sid:2432 tty:/dev/pts/0 cwd:/root filename:/bin/tail]: tail -f /var/log/secure
Dec  1 13:22:59 sshgw snoopy[2592]: [uid:1000 username:u1ymd sid:2544 tty:/dev/pts/1 cwd:/home/u1ymd filename:/usr/bin/ps]: ps -ef
Dec  1 13:23:07 sshgw snoopy[2594]: [uid:1000 username:u1ymd sid:2544 tty:/dev/pts/1 cwd:/home/u1ymd filename:/usr/bin/uname]: uname -a
```


あとはSyslogサーバーへ諸々のログと一緒に飛ばしておく



# SlackにSSHログイン通知を飛ばす

### SSHログイン時に実行するスクリプト



```config:/etc/ssh/sshrc
/opt/sh/sshlogin.sh "$USER" "$SSH_CLIENT"
```


/opt/sh/sshlogin.sh
※ root以外でも実行できるよう権限変えておく

```shell:/opt/sh/sshlogin.sh
#!/bin/sh

#チャンネル
CHANNEL=${CHANNEL:-"#ssh_login"}
#名前
APPNAME=${APPNAME:-"SSH Gateway Login"}
#アイコン
ICON=${ICON:-":key:"}
#メッセージ内容
MESSAGE=${MESSAGE:-"*$1* が *$2* から踏み台SSHサーバーにログインしました"}
#WebHookUrl
WEBHOOKURL="https://hooks.slack.com/services/hogehoge/hogehoge"

curl -s -S -X POST --data-urlencode "payload={\"channel\": \"${CHANNEL}\", \"username\": \"${APPNAME}\", \"icon_emoji\": \"${ICON}\", \"text\": \"${MESSAGE}\" }" ${WEBHOOKURL} >/dev/null
```

ただし、ユーザーのホームディレクトリに　~/.ssh/rc が作成されると
 /etc/ssh/sshrc は実行されなくなります・・・。

こんな感じで通知されます。

<img width="474" alt="名称未設定.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85470/0fda896e-0d3e-a5e3-ca83-8a5f3344b85f.png">


# firewalldでユーザー/グループ毎に通信を制限する

### 制限ユーザーのグループを作る


`# groupadd restricted-users`



### firewalldのdirectルール追加（OUTPUT）

「md-restricted」グループのユーザーはDNS問い合わせは許可して、それ以外は全部拒否

```
# firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 101 -m owner --gid-owner restricted-users -m tcp -p tcp --dport 53 -j ACCEPT

# firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 101 -m owner --gid-owner restricted-users -m udp -p udp --dport 53 -j ACCEPT

# firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 999 -m owner --gid-owner restricted-users -j REJECT

# firewall-cmd --reload
success

# firewall-cmd --direct --get-all-rules
ipv4 filter OUTPUT 101 -m owner --gid-owner restricted-users -m tcp -p tcp --dport 53 -j ACCEPT
ipv4 filter OUTPUT 101 -m owner --gid-owner restricted-users -m udp -p udp --dport 53 -j ACCEPT
ipv4 filter OUTPUT 999 -m owner --gid-owner restricted-users -j REJECT
```

OUTPUTの後ろの数字は優先順位の重み付け
999で「restricted-users」グループのOUTPUTは全てREJECTされるので
許可ルールは若い数字で追加していく。


## 制限グループにユーザー追加

```
# useradd seigenuser -g restricted-users
```

作成した「seigenuser」でログイン
ログイン後は想定通りDNS名前解決以外は何もできない。

次に192.168.0.100へのSSHだけ許可してみる

```
# firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 102 -m owner --gid-owner restricted-users -m tcp -p tcp -d 192.168.0.100 --dport 22 -j ACCEPT

# firewall-cmd --reload
```


「--uid-owner」であればユーザー単位の制御も可能


削除するときは「--remove-rule」

```
# firewall-cmd --permanent --direct --remove-rule ipv4 filter OUTPUT 102 -m owner --uid-owner restrict-user -m tcp -p tcp -d 192.168.0.100 --dport 22 -j ACCEPT

# firewall-cmd --reload
```

# その他で実施しておいたこと


## コマンド制限

psやwで、他のユーザーが実行中のコマンドが見えてしまうのでコマンドの実行権限をrootだけにした

```
# ls -l /bin/ps
-rwxr-xr-x 1 root root 100120  8月  4 20:12 /bin/ps

# chmod o-x /bin/ps

# chmod o-x /bin/w

# ls -l /bin/w
-rwxr-xr-- 1 root root 19904  8月  4 20:12 /bin/w

# ls -l /usr/bin/w
-rwxr-xr-- 1 root root 19904  8月  4 20:12 /usr/bin/w

# ls -l /bin/ps
-rwxr-xr-- 1 root root 100120  8月  4 20:12 /bin/ps

# ls -l /usr/bin/ps
-rwxr-xr-- 1 root root 100120  8月  4 20:12 /usr/bin/ps

```

```
$ ps aux
-bash: /usr/bin/ps: 許可がありません

$ w
-bash: /usr/bin/w: 許可がありません
```

## SSHタイムアウト対策

踏み台経由のSSH接続時のタイムアウト対策で
/etc/ssh/ssh_config　に以下を追記した

```
ServerAliveInterval 15
```