SSHサーバー(sshd)のアクセス制限

sshd のアクセス制限は、「/etc/ssh/sshd_config.d/」で行うと細かな制御が行える。

root のログイン許可/拒否

「/etc/ssh/sshd_config.d/」ディレクトリに「PermitRootLogin.conf」などのファイルを作り指定する。

もちろん「no」を指定すれば拒否となる。

アクセス制限

アクセス制限はアカウント指定やアドレス指定、ドメイン指定などが行える。

「/etc/ssh/sshd_config.d/」ディレクトリに「AllowUsers.conf」などのファイルを作り指定する。

この場合は、許可したユーザーのみがログイン可能となる。

※ 「*」などのワイルドカードが使用できる。

また、「DenyUsers」として記述する方法もあり、次の様に指定すると、拒否ユーザーを指定する事も出来る。 この場合は、拒否したモノ以外は許可となる。

この他にも「AllowGroups」や「DenyGroups」といった指定方法もある。

Python で ssh、scp、ftp、rsync を利用する

Python では、ssh、scp、ftp、rsync などは subprocess では制御出来ない。

そこで、それを可能にする pexpect について解説する。

pexpect とは

単純に言えば「expect」コマンドの Python 版です。

しかしながら、コマンドの入出力が Python で操作できるため、「expect」よりも簡単に習得出来る。

例えば、コマンド出力を正規表現を用いて制御出来るため、補足が簡単になるなどのメリットがある。

pexpect のインストール

$ sudo dnf install python3-pexpect

コマンドの起動

pexpect.spawncommandargs=[]timeout=30maxread=2000searchwindowsize=Nonelogfile=Nonecwd=Noneenv=Noneignore_sighup=Falseecho=Truepreexec_fn=Noneencoding=Nonecodec_errors= ‘strict’Dimensions=Noneuse_poll=False )

これを実行する事により操作ハンドルが得られる。

なお、日本語環境では「encoding=’utf-8’」は必須。

コマンド出力の取得

expectpatterntimeout=-1searchwindowsize=-1async_=False**kw )

操作ハンドルに対して出力を得る。

なお、パターンは正規表現であり、配列で渡すことで、複数指定できる。

複数指定した場合は、ヒットした番号が得られる。(0始まり)

行の送信

sendlines=” )

パスワードの送信などに用いる。

コマンドの終了

sendeof( )

コマンドを終了したい場合に送信する。

例:

p = pexpect.spawn('scp /tmp/A/a.txt root@localhost:/tmp/B/b.txt', encoding='utf-8')
index = p.expect([r'.*yes.*', r'(.*パスワード:)|(.*password:)', pexpect.EOF, pexpect.TIMEOUT])
if index == 1: #2番目の正規表現に一致(0はじまり)
        p.sendline('パスワード')
        print("password send")
        p.sendeof()

参考:

Core pexpect components

その他:

sshpass を利用する方法もある。

ssh、scp、rsync などをシェルから実行する

コマンドの「ssh」や「scp」、「rsync」などは通常の方法ではシェル(バッチ)で実行できない。

これはパスワードの入力が端末からの入力に限定され、標準入力や標準出力を用いた制御を行なえない為だ。

これを回避する方法としては「expect」が有名であるが、パスワード入力が SSH を用いて行なわれている場合に限り、「sshpass」で簡単に制御出来る。

sshpass に出来ること

sshpass に出来ることは、パスワードを指定してコマンドを実行すだけである。 そのためサーバー証明書を受け付ける(yes/no)には対応していない。

そのため最初にサーバーに接続す場合には(yes/no)でキーを受け付けている必要がある。

sshpass のインストール

$ sudo dnf install sshpass

sshpass の使用方法

sshpass -p “パスワード” コマンド [コマンド引数…]

sshpass の使用例

sshpass -p “パスワード” scp /tmp/a.text root@example.com:/tmp/a.txt

sshpass -p “パスワード” rsync -aux /tmp/A root@example.com:/tmp/B

基本的には、「ssh -p “パスワード”」の後に、実行したいコマンドを書くだけである。

rsync でバックアップ

rsync コマンドを利用すれば簡単にバックアップが取れる。そこで今回は rsync コマンドにいて説明します。


rsync コマンドの基本

rsync コマンドの使い方は次の通りです。


同一マシン内でのバックアップ

rsync -au  SRC_PATH/  DEST_PATH
  • 「a」
    アーカイブモードで行う(ファイル属性などを保持する)
  • 「u」
    更新分のみコピーを行う
  • SRC_PATH
    コピー元のディレクトリ(絶対または相対パス)
    末尾に「/」を付ける
  • DEST_PATH
    コピー先のディレクトリ(絶対または相対パス)
    末尾に「/」を付けない

マシン間でのバックアップ

rsync -auz  SRC_PATH/  user@host:DEST_PATH
rsync -auz  user@host:SRC_PATH/  DEST_PATH
  • 「a」
    アーカイブモードで行う(ファイル属性などを保持する)
  • 「u」
    更新分のみコピーを行う
  • 「z」
    マシン間での転送は圧縮して行う
  • 「user」
    マシンに接続するユーザーアカウント
  • 「host」
    接続するマシン名称または IP アドレス
  • SRC_PATH
    コピー元のディレクトリ(絶対または相対パス)
    末尾に「/」を付ける
  • DEST_PATH
    コピー先のディレクトリ(絶対または相対パス)
    末尾に「/」を付けない

「user@host:PATH」では host マシンの user にログインした状態ですので、続くパス(PATH)は相対パスまたは絶対パスになります。

基本的に「ssh」接続になりますので、「~/.ssh/known_hosts」に対象マシンがあるかどうかで挙動が変わります。


マシン間でのバックアップを自動化

異なるマシン間でバックアップを取る時、通常はパスワードが聞かれます。

この時、パスワード入力はキーボード入力で行われるので、通常のバッチファイルで行う場合は一工夫必要です。

パスワードファイルを作成して行う

パスワード記載したファイルを「FILE」として保存し、「–password-file=FILE」を使用する

rsync -auz --password-file=FILE  SRC_PATH/  user@host:DEST_PATH
rsync -auz --password-file=FILE  user@host:SRC_PATH/  DEST_PATH

expect コマンドを使用して行う

expect -c 'spawn rsync -auz  SRC_PATH/  user@host:DEST_PATH ; expect "password:" ; send "PASSWORD\n" ; expect wait'
expect -c 'spawn rsync -auz  user@host:SRC_PATH/  DEST_PATH ; expect "password:" ; send "PASSWORD\n" ; expect wait'

PASSWORD」の部分にパスワードを指定

sshpass コマンドを使用して行う

sshpass -p "PASSWORD" rsync -auz SRC_PATH/  user@host:DEST_PATH
sshpass -p "PASSWORD" rsync -auz user@host:SRC_PATH/  DEST_PATH

PASSWORD」の部分にパスワードを指定

root アカウントを有効にする

Fedora のインストール直後では、スーパーユーザー「root」アカウントにはグインできない。

そこで、一般ユーザーにログインした状態で端末を表示し、次のように入力する。

$ sudo bash
パスワード:
# passwd
ユーザー root のパスワードを変更。
新しいパスワード:
新しいパスワードを再入力してください:
passwd: すべての認証トークンが正しく更新できました。

これで、root アカウントにログイン出来るようになる。

また、他のマシンから root にログイン出来るようにする為には、ssh サーバーを有効にしてから、設定を行う必要がある。

$ su       # root にログイン
パスワード:
# echo "PermitRootLogin yes" > /etc/ssh/sshd_config.d/PermitRootLogin.conf
# systemctl enable sshd
# systemctl start sshd

これで、他のマシンからも root にログインできる。

※ ssh を用いて、他のマシンからログインするためには、予めファイヤーウォールの sshd のポートを開放している必要があります。詳しくはコチラ