VLAN Trunkポートのキャプチャ

Trunkポートを流れるパケットのVLANタグをWiresharkでキャプチャしたい。と思ったときに思いのほか手順が多かったのでメモとして残す。

ざっくり手順

上記構成でパケットキャプチャの手順は次の通り。

  1. SW1にてキャプチャの設定
  2. キャプチャを行うPCで802.1qのタグを落とさないよう,キャプチャを取得するNICのドライバ設定
  3. Wiresharkで802.1qのタグをキャプチャ画面の列に表示するよう設定

通常のアクセスポートでキャプチャを行うだけであれば意識することなくできると思うが,VLAN Trunkポートにおいては各手順でいつもと違う設定が必要になる。

SW1でmonitor session 設定

通常のキャプチャであれば

monitor session 1 source interface Gi0/1
monitor session 1 destination interface Gi0/2

とシンプルに設定をすればよいが,デフォルトではタグ情報を外して宛先ポートへパケットが転送されるため「encapsulation」オプションで「replicate / dot1q」を指定する必要がある。カプセル化でISLを設定するケースはまず無いと思うので,このオプションはdot1qでTrunk設定しているならばどちらでも良いと思う。オプションの違いは,送信元IFと同じカプセル化・設定を指定する場合は「replicate」,dot1qの設定とするならば「dot1q」という感じ。(※ IOSの場合)

なお,受信パケットでにおいて特定のVLANを限定して取得したい場合は「ingress dot1q vlan」オプションでVLAN IDを指定する。

(任意)宛先インターフェイスで IEEE 802.1Q カプセル化方式の使用を指定するには、 encapsulation dot1q を入力します。
(任意)送信元インターフェイスのカプセル化方式が宛先インターフェイスで複製されるように指定するには、 encapsulation replicate を入力します。これを選択しない場合、デフォルトでは、パケットがネイティブ形式(タグなし)で送信されます。
宛先ポートでの着信トラフィックの転送をイネーブルにして、カプセル化タイプを指定するには、 ingress をキーワードと一緒に入力します。
– dot1q vlan vlan-id: デフォルトの VLAN として指定した VLAN で、IEEE 802.1Q でカプセル化された着信パケットを受信します。
– untagged vlan vlan-id または vlan vlan-id: デフォルトの VLAN として指定した VLAN で、タグなしでカプセル化された着信パケットを受信します。

cisco.com/c/ja_jp/td/docs/sw/lanswt-access/cat2960swt/cg/005/swcfg/swspan.html

よって次のような設定を入れる。

monitor session 1 source interface Gi0/1
monitor session 1 destination interface Gi0/2 encapsulation replicate  # dot1q でもOK

NICの設定

およそのNICはデフォルトでVLANタグを落とす設定になっているため,NICの詳細設定で「Packet Priority&VLAN」を「Disable」にする。※デフォルトでは「Enable」になっているはず

この設定ができない(VLANタグをそのまま受信できない)NICもあるようで,NICの対応状況は予めチェックが必要。今回利用したNICはStarTechのUSBタイプ。

Wiresharkの設定

Wiresharkのキャプチャ画面の項目(列)にはVLAN情報がデフォルトでは表示されないため,VLAN IDを表示させるため外観設定を変更する。パケットを選択すればVLANフィールドがあるので別に要らないという人はここはやらなくてもOK。ただぱっと見どのVLANか分かるので可視性はよい。

Wiresharkを立ち上げ,「編集」→「設定」で設定画面表示。

「+」ボタンを押してフィールドを追加し,フィールドに「vlan.id」を入力する。題名はお好きなように。ここでは「VLAN」とした。

これで準備完了。

キャプチャする

VLANが表示されて幸せになれる。

ちなみに,QinQを表示させたい場合は,Wiresharkで追加するフィールドに「ieee8021ad.id1」を入力する。

  1. Display Filter Reference: IEEE 802.1ad (https://www.wireshark.org/docs/dfref/i/ieee8021ad.html ↩︎

no ip domain-lookupからの卒業

Smart Licenseのおかげでスイッチにおいてもip domain-lookupの設定が必要になった。(環境によりけりが,インターネットダイレクト構成では少なくとも必要)

これを入れるとコマンド打ち間違えの時にdomain-lookupが発動してしまい,暫しご歓談をタイムに陥ってしまう。ミスタイプなどしないS級エンジニアや,「少しくらいの時間ならお茶を飲みながら待ちますよ」という賢者ならまだしも,ミスタイプをしょっちゅうするし少しの待ち時間ももったいない私にとっては致命的。

ということで方法はないかと調べてみると,あったのねこんな所に

“no ip domain-lookup”の代わりに”transport preferred none”

http://blog.livedoor.jp/tokyo_z/archives/51247251.html

間違えたコマンド入力を名前解決をしない方法

http://networkerslog.blog137.fc2.com/blog-entry-335.html

Transport preferred

https://community.cisco.com/t5/switching/transport-preferred/td-p/1612979

オフィシャルサイトでは以下のように説明がある。IOS XRだけど,基本同じだろう。

Cisco IOS XR ソフトウェア は、認識できないコマンドはすべてホスト名であるものと想定し、接続を試みます。 プロトコルが none に設定されている場合、システムは EXEC プロンプトで入力された認識できないコマンドを無視し、接続を試みません。

https://www.cisco.com/c/ja_jp/td/docs/rt/servprovideredgert/asr9000aggregationservsrt/cr/035/b_sysman_cr42asr9k/b_sysman_cr42asr9k_chapter_010010.html#wp2132003449

何かの名残でこのような設定になっているのかな。ちなみにIOS XRではデフォルト無効になっているそうだ。IOSやIOS XEでも同じくデフォルト無効にして欲しい。

以下設定コマンド。これでコマンド以外の文字列が入力されてもlookupが走らない(正確にはtelnetコマンドが実行されない)。

line con 0
 transport preferred none
line vty 0 4
 transport preferred none

NW機器のTACACS+設定

およそ世間では情報が沢山あるので我が家の設定値のみ記載。

設定方針は次の通り。

  • 1号機は.20,2号機は.21,TACACSサーバがダウンしたらLocal認証(タイムアウトは5秒)
  • ログインできたら即特権(コマンド権限はTACACSサーバ側で握る)
  • 1号機を最初に記述,2号機を次に記述
  • aaaの設定でdefaultとして定義するものをよく見かけるが,自宅環境では不採用とし,各aaaの定義に名前を付ける。(仮にdefaultで定義すると全てのインタフェースに適用されるし,設定順番ミスるとそのままコマンドがはじかれるなどリスクがあると思う。ただし,line vty でのauthentication設定などは不要になるなど設定行は減る。)

Cisco IOS

!!! AAA有効
aaa new-model

!!! TACACSサーバ登録。aaa tacacs-server は非推奨になった模様。
tacacs server tacacs-sv1
 address ipv4 192.168.30.20
 key <tacacsサーバで設定したKey>
 timeout 5
tacacs server tacacs-sv2
 address ipv4 192.168.30.21
 key <tacacsサーバで設定したKey>
 timeout 5

!!! TACACSサーバグループ作成。
aaa group server tacacs+ TAC_SRV
 server name tacacs-sv1
 server name tacacs-sv2

!!! TACplusという名前でTAC_SRVで登録したTACACSサーバに問い合わせる。落ちてたらローカル認証。
aaa authentication login TACplus_authe group TAC_SRV local-case


!!! 実行権限をTACACSサーバに問い合わせる。落ちてたらローカル認証。
aaa authorization exec TACplus_autho_exec group TAC_SRV local

!!! 実行レベル15のコマンド実行権限をTACACSサーバに問い合わせる。落ちてたらローカル認証。
aaa authorization commands 15 TACplus_autho_cmd group TAC_SRV local

!!! コマンド実行ログをTACACSサーバへ送信。
aaa accounting commands 15 TACplus_acco start-stop group TAC_SRV



line vty 0 4
 exec-timeout 0 0
 authorization commands 15 TACplus_autho_cmd
 authorization exec TACplus_autho_exec
 logging synchronous
 login authentication TACplus_authe
 transport input ssh

Cisco ASA

ASAの場合はIOSとは若干違うが,基本的な定義の流れは同じ。

aaa-server TACplus protocol tacacs+
 reactivation-mode timed
 max-failed-attempts 2
aaa-server TACplus (mgmtside) host 192.168.30.20
 key *****
aaa-server TACplus (mgmtside) host 192.168.30.21
 key *****

!!! SSH接続時にTACACS→LOCALという順で認証
aaa authentication ssh console TACplus LOCAL

!!! 特権
aaa authentication enable console TACplus LOCAL

aaa authorization command TACplus LOCAL
aaa accounting command privilege 15 TACplus

!!! 
aaa authorization exec authentication-server auto-enable
aaa authentication login-history

以上。

NICのTeaming設定(RHEL)

想定構成

以下構成で10GbpsのNICを2本束ねる。

参考URL  nmcli を使用したネットワークチーミングの設定

  1. チーミングインタフェースを作成
  2. 物理IFをチーミングに所属
  3. チーミングIFを有効化

teamingを設定する方法にはいくつかあるが,ここでは公式ドキュメント最初に出てくるnmcliを利用して設定する。なお,teamdは永続性がないためnmcliやifcfgファイルで設定する方がよさそう。

想定する設定は,

  1. interfaceは「enp1s0f0」「enp1s0f1」の2つを利用。
  2. LACP利用
  3. 送信負荷分散のハッシュ値にmac address(scx/dst), ip address(src/dst), tcp port(src/dst) の3つを含める。

Teamingインタフェース作成

nmcliコマンドでTeamingの論理インタフェースを作成する。

# nmcli connection add type team ifname team0 con-name team0 config '{"device": "team0", "runner": {"name": "lacp", "active": true, "fast_rate": true, "tx_hash":  ["eth", "ipv4", "ipv6", "l4"]}, "link_watch": {"name": "ethtool"}}'
接続 'team0' (380df2de-dcef-4436-aded-9c4ab20e13e6) が正常に追加されました。

team0に所属させるインタフェースを設定する。オプションで「con-name」をつけると別名でインタフェースを定義できるが指定しないと「team-slave-enp1s0f0」のようになる。

# nmcli con add type team-slave ifname enp1s0f0 master team0
# nmcli con add type team-slave ifname enp1s0f1 master team0

IFの有効化

物理IF,TeamingIFのどちらを有効にしてもよい。

# nmcli con up team-slave-enp1s0f0
接続が正常にアクティベートされました (D-Bus アクティブパス: /org/freedesktop/NetworkManager/ActiveConnection/22)
# nmcli con up team-slave-enp1s0f1
接続が正常にアクティベートされました (D-Bus アクティブパス: /org/freedesktop/NetworkManager/ActiveConnection/25)

# nmclie con up team0
# ip link
18: team0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000
    link/ether 00:1b:21:6e:82:1d brd ff:ff:ff:ff:ff:ff

IPアドレスが設定されないとUPにならないが,後々内部ブリッジに接続させる予定なので今回はここまで。

cronの期間指定

cronの書き方で毎度悩む期間指定。めったに触らないから調べても忘れる。

ということでメモ。

基本的な記述は,「分,時,日,月,曜日」の5つのフィールドに指定したい値を書く。

cron(8) examines cron entries every minute.

The time and date fields are:

    field          allowed values
     -----          --------------
     minute         0-59
     hour           0-23
     day of month   1-31
     month          1-12 (or names, see below)
     day of week    0-7 (0 or 7 is Sunday, or use names)

毎時,毎月などは スラッシュで指定する。例えば「2時間毎に」としたいならば

* */2 * * * 

とする。それは分かる。だがしかし,これは何処を起点に2時間をカウントしはじめるのだろう,設定した時間からカウント始めるのか?それとも0時0分をスタートとして0,2,4,6,8,10,12,・・・としていくのだろうか?と毎度分からなくなる(忘れる)。ソースコードを読み解けば分かるのかもしれないが,そんな技量はないので実際に設定して確認する。

*/3 * * * * date >> /home/user/check

このときの実行状況は以下の通り。

2021年  3月 13日 土曜日 10:18:01 JST
2021年  3月 13日 土曜日 10:21:01 JST
2021年  3月 13日 土曜日 10:24:01 JST
2021年  3月 13日 土曜日 10:27:01 JST
2021年  3月 13日 土曜日 10:30:01 JST
2021年  3月 13日 土曜日 10:33:01 JST
2021年  3月 13日 土曜日 10:36:01 JST
2021年  3月 13日 土曜日 10:39:01 JST

0分からカウントされているっぽい。では41分に4分間隔に変更するとどうだろう。

*/4 * * * * date >> /home/user/check

41分からカウント開始とするなら45分に実行されるはずだが,0分スタートとするならば,44分に実行されるはず。

2021年  3月 13日 土曜日 10:39:01 JST
2021年  3月 13日 土曜日 10:44:01 JST

44分。デスヨネ。なんとなく気づいていましたよ。everyや毎にという言葉が悪い(違。

ただ,そうすると「50分毎に」や「9ヶ月毎に」など時刻ベースではなく純粋に時間間隔で実行したいときはどうするのだろう。

50 * * * *

とすると,0時50分,1時50分,2時50分と毎時50分になる。cronではそういうことは想定していないのだろうな。そもそもマニュアルに“run this command at this time on this date”ってあるしね・・・。個別にスクリプトを書くしかないのか。

Catalyst3560CでGREトンネル

とある検証でL3SWでGREトンネルのみ張る設定を確認した。普通にいけるかなと思ったが,keepaliveでひっかかったのでメモ。

基本的には,Vlan IFにIPアドレスを設定し,tunnel source / destination でそれぞれ指定すれば完了。ただし,Keepaliveを設定するとDownとなる。デバッグをとっても応答が返ってこず(recieveが無い)Down判定されていた。

interface Tunnel1
 ip address 192.168.254.2 255.255.255.252
 keepalive 5 2
 tunnel source Vlan1
 tunnel destination 192.168.10.1

なんでだろうなと調べてみると,以下の一文を見つけた。

Support is available for gre ip tunnel mode. The tunnel source can be loopback and Layer 3 (physical or Etherchannel) interfaces only.

https://www.cisco.com/c/dam/en/us/td/docs/switches/lan/catalyst3850/software/release/16-1/workflows/gre-feature-guide.pdf

なるほど。型番もバージョンも違うけれどこれっぽい。試しにip routingを有効にしてLoopback IFを追加,対向のLoに対するスタティックルート追加したところ無事にkeepalive有りでトンネルが張れた。

枯れた技術だけれど,結構まだハマるところがあるという。精進が足りませんね。

Microsoft Azure Fundamentals

先日,Microsoftのオンラインセミナー受講したらバウチャーを配布してくれたので受験してきました。
Azureの初級という位置づけで,「クラウド初めてさわる」「これからAzure案件に関わる予定」という人向けのようです。(個人的には新人のスキルアップに丁度良い教材&資格ではないかと思っています。)

私自身は初心者ではありませんが,Azureというクラウドサービスを理解するというきっかけには丁度良い試験でした。もちろんセミナーを受けただけでは受からないので

  • Microsoftのラーニングパスを通して理解を深める。
  • Azureアカウントを作成して一通り操作や見方を覚える。

と,ある程度対策をしたうえで受験し,無事に合格しました。

個人的にオススメラーニングパスは以下の通り。

Microsoft Azure クラウドの概念について調べる (AZ-900) ・・・ 4つのモジュールがあり,これはオンラインセミナーと結構重複していたので,復習のためやっておくと良い。

Azure の基礎 ・・・ 12個のモジュールがある。実際にAzureを操作してVMや可用性ペアを作るなどのハンズオンが盛り込まれている。まったくのクラウド初心者だと,これくらいまでは最低限やっておかないと厳しいかもしれない。

以下のモジュールでさらに理解を深めておくと余裕をもっていけるはず。ただ,受けた感想として,クラウド一般的な技術の話というよりは,Azureに特化したサービス(ポリシー/課金/サポート)に重点を置いて対策をとったほうがよいと感じた。

Azureを触ってみてAWSとは違う使いやすいさ,チュートリアルの豊富さが良いと感じたので今後個人的にも使ってみよう。

WordPress構築

Bloggerを使っていたけれど,使い勝手がよいWiki形式へ切り替えたいと思い,勉強がてらWordpressを自前で立ててこちらへ引っ越し。

1発目はWordpress構築メモ。

構想

イメージ
構成概要

構成イメージはこのような感じ。GCP上にCentOS8の仮想マシンを1つたて,その上で完結させる。DBは分けた方がよいのだろうが,まずは無事に立ち上がるところまで。

ドメインはさくらインターネットで取得。.comドメインで年間1886円。GCPでグローバルIPアドレスを確保した後,設定画面でDNS登録をする。

大まかな流れ

  1. DBインストール,設定
  2. PHPインストール,設定
  3. HTTPDインストール,設定
  4. HTTPS化

いざゆかん。

とその前に,構築中は自宅からのみアクセス可能とするためGCPのファイアウォールでソースIPアドレスを限定する。

DBインストール,設定

オフィシャルサイトを参考。

$ sudo dnf install mariadb-server.x86_64

DBセキュア化

$ sudo mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none):
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n] y
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
 ... Success!

By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

wordpress用DB設定。

MariaDB [(none)]> CREATE DATABASE wordpress;
Query OK, 1 row affected (0.004 sec)


MariaDB [(none)]>


MariaDB [(none)]> GRANT ALL PRIVILEGES ON wordpress.* TO "DBアドミン名"@"localhost" IDENTIFIED BY "パスワード";
Query OK, 0 rows affected (0.004 sec)


MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.002 sec)

ログに認証エラーが出た。ケルベロス認証などは使わないので無効化で対処する。

[ERROR] mysqld: Server GSSAPI error (major 851968, minor 2529639093) : gss_acquire_cred failed -Unspecified GSS failure. Minor code may provide more information. Keytab FILE:/etc/krb5.keytab is nonexistent or empty.
/var/log/mariadb/mariadb.log の内容
$ sudo mv /etc/my.cnf.d/auth_gssapi.cnf /etc/my.cnf.d/auth_gssapi.cnf.org

起動設定。

$ systemctl enable mariadb
$ systemctl start mariadb

PHPインストール,設定

$ sudo dnf install php php-mysqlnd php-mbstring.x86_64 php-json php-gd php-xml php-zip php-dom

php-gdがないとwordpress上で画像の編集ができない

推奨

参考) https://qiita.com/kogache/items/00dc37774dfe20f03a72

/etc/php-fpm.d/www.conf 編集。httpdとしてnginxを使うのでユーザとグループを修正する。

; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
; RPM: apache user chosen to provide access to the same directories as httpd
;user = apache
user = nginx
; RPM: Keep a group allowed to write in log dir.
;group = apache
group = nginx

nginxインストール,設定

$ sudo dnf install nginx

wordpress設定

wordpressもあわせてインストールをする。今回は /usr/share/nginx の下に WP というディレクトリを作成して,そこへwordpressを配置する。

$ wget https://ja.wordpress.org/latest-ja.tar.gz
$ tar xvfz latest-ja.tar.gz ./
$ sudo chown -R nginx:nginx /usr/share/nginx/WP
$ sudo mv wordpress/* /usr/share/nginx/WP/

nginx設定ファイル変更。 /etc/nginx/conf.d/wp.conf として編集。TLS1.2 と1.3に限定する。こちらを参考。

# HTTPSへリダイレクト
server {
        listen 80;
        server_name zassoul.com;
        return 301 https://$host$request_uri;
}
server {
        listen 443 ssl;
        server_name zassoul.com;
        root /usr/share/nginx/WP;
        index index.php;
        charset utf-8;

        ssl_certificate /etc/letsencrypt/live/zassoul.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/zassoul.com/privkey.pem;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;

        location = /favicon.ico {
                log_not_found off;
                access_log off;
        }

        location / {
                try_files $uri $uri/ /index.php?$args;
        }

        # Deny to wp-config.php
        location ~* /wp-config.php {
                deny all;
        }

        #php-fpm
        location ~ \.php$ {
                try_files $uri = 404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                include fastcgi_params;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_pass php-fpm;
        }

        location ~* \.(js|css|png|jpg|jpgeg|gif|ico)$ {
               expires max;
               log_not_found off;
        }
}

wp-config.php を編集する。(オフィシャルサイトを参考)

// ** MySQL 設定 - この情報はホスティング先から入手してください。 ** //
/** WordPress のためのデータベース名 */
define( 'DB_NAME', 'wordpress' );

/** MySQL データベースのユーザー名 */
define( 'DB_USER', '上で設定したユーザ名' );

/** MySQL データベースのパスワード */
define( 'DB_PASSWORD', '上で設定したパスワード' );

/** MySQL のホスト名 */
define( 'DB_HOST', 'localhost' );

/** データベースのテーブルを作成する際のデータベースの文字セット */
define( 'DB_CHARSET', 'utf8mb4' );

/** データベースの照合順序 (ほとんどの場合変更する必要はありません) */
define( 'DB_COLLATE', '' );

/**#@+
 * 認証用ユニークキー
 */
define( 'AUTH_KEY',         'ジェネレートしたキー' );
define( 'SECURE_AUTH_KEY',  'ジェネレートしたキー' );
define( 'LOGGED_IN_KEY',    'ジェネレートしたキー' );
define( 'NONCE_KEY',        'ジェネレートしたキー' );
define( 'AUTH_SALT',        'ジェネレートしたキー' );
define( 'SECURE_AUTH_SALT', 'ジェネレートしたキー' );
define( 'LOGGED_IN_SALT',   'ジェネレートしたキー' );
define( 'NONCE_SALT',       'ジェネレートしたキー' );

/**#@-*/

HTTPS化

常時HTTPSもするのでLet’s EncryptでSSL証明書を発行する。サイト認証のため80番ポートでアクセスしてくる必要があるということで,一時的に80番ポート全解放をする。

こちらを参考にLet’s Encryptで証明書発行を実施。

Certbotのインストール。

$ sudo dnf install epel-release
$ sudo dnf install certbot

お試しdry-run。

$ sudo certbot certonly --dry-run --standalone -w /usr/share/nginx/WP/ -d zassoul.com -m "Email-Address"

本番実行。

$ sudo certbot certonly  --standalone -d zassoul.com -m "Email-Address" --agree-tos
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for zassoul.com
Using the webroot path /usr/share/nginx/WP for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Subscribe to the EFF mailing list (email: "Email-Address").


IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/zassoul.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/zassoul.com/privkey.pem
   Your cert will expire on 2020-12-07. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:


   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

ここで80番を閉じる。nginx起動設定。

$ sudo systemctl enable nginx
$ sudo systemctl start nginx

完了。

LinuxでPBR

AWSでインスタンスを立ち上げたとき,2つのサブネットに所属させ一方は社内ネットワーク,一方はメンテナンス用に外部(インターネット)からSSHアクセス用にと構成することがある。

この場合,それぞれのNICに着信したトラフィックはそのNICから応答を返して欲しいが通信元が不特定だとスタティックルートで処理するのは不可能。このような時はPBRを設定して対応する。
参考) 

手順

  • ルートテーブルの作成
  • ポリシーの作成
  • ルーティングの追加
  • 永続的設定

ルートテーブルの作成

/etc/iproute2/rt_tables にens192用のルーティングテーブル「rt10」とens224用のルーティングテーブル「rt100」を追加する。なお,IDは1~255まであり,254はmainテーブル,255はlocalでリザーブされている。ここでは100と101を使用する。
#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
#1 inr.ruhep
100 rt100 #追加
101 rt10 #追加

ポリシーの作成

書式: ip rule add from <IF address> table <table name> priority <priority number>
# ip rule add from 192.168.10.40 table rt10 priority 100
# ip rule add from 192.168.1.40 table rt100 priority 101

prioritを指定しないとカーネルが一番古いpriorityの前に自動で採番する。何も設定されていなければmainの32766の前に順に追加される。(32765,32764という感じで)

ルーティングの追加

書式: ip route add default via <Gateway address> dev <IF name> table <table name> 
# ip route add default via 192.168.10.1 dev ens192 table rt10
# ip route add default via 192.168.1.1 dev ens224 table rt100
まずはこれでPBRは設定完了。
192.168.1.0/24にいるPCからpingのテスト。
PBR設定前はens192からreplyが返っていない。(なお,リバースパスフィルタリングが有効になっているのでens224では戻りのパケットがかえらない)
PBR設定後はしっかり着信IFからreplyが返っている。

永続的設定

コマンドで設定したルールとルートは再起動で消えるため,/etc/sysconfig/network-script配下に定義ファイルを作成するとあったが,NetworkMangerを利用している環境では利用できない。

・ ルール定義

/etc/sysconfig/network-script/rule-<IF名>
各IFに先のコマンドを記述。
ip rule add from 192.168.10.40 table rt10 priority 100
ip rule add from 192.168.1.40 table rt100 priority 101

・ ルート定義

/etc/sysconfig/network-script/route-<IF名>
各IFに先のコマンドを記述。
ip route add default via 192.168.10.1 dev ens192 table rt10
ip route add default via 192.168.1.1 dev ens224 table rt100
これがNGとなると,起動スクリプトに上のコマンドを実行するように仕込む方法が考えられる。
pbr.sh
#!/bin/sh
## create rules for pbr

ip rule add from 192.168.10.40 table rt10 priority 100
ip rule add from 192.168.1.40 table rt100 priority 101

## create default route for each routing tables
ip route add default via 192.168.10.1 dev ens192 table rt10
ip route add default via 192.168.1.1 dev ens224 table rt100
/etc/systemd/system/pbr.service
[Unit]
Description = PBR setting script
After = network-online.target # NICがオンラインにならないとコマンドが失敗に終わるため

[Service]
ExecStart = /root/pbr.sh
Type = simple

[Install]
WantedBy = multi-user.target

ここまで準備できたら
# systemctl enable pbr.service
# systemctl start pbr.service
で完了。
ただここまでやっておきながら,nmcliを使えばコマンド1行で終わることが分かった。

nmcliを使う方法

ens192の設定
nmcli con add type ethernet con-name ens192 ifname ens192 ipv4.method manual ipv4.addresses 192.168.10.40/24 ipv4.routes "0.0.0.0/1 192.168.10.1 table=100, 128.0.0.0/1 192.168.10.1 table=100" ipv4.routing-rules "priority 100 from 192.168.10.40 table 100"
ens224の設定
nmcli con add type ethernet con-name ens224 ifname ens224 ipv4.method manual ipv4.addresses 192.168.1.40/24 ipv4.routes "0.0.0.0/1 192.168.1.1 table=101, 128.0.0.0/1 192.168.1.1 table=101" ipv4.routing-rules "priority 101 from 192.168.1.40 table 101"
以上。超簡単。再起動後もこれで対応している。
RHELの公式ドキュメントによると,nmcliは0.0.0.0/0の表記に対応していないとのことで,0.0.0.0/1と128.0.0.0/1の2つ定義を入れて0.0.0.0/0をカバーしなくてはならないとのこと。この点とテーブルを名前指定ができず番号で記述する必要があるのがややわかりにくい。
ちなみにIFの設定ファイルは以下にある。
/etc/NetworkManager/system-connections/ens192.nmconnection 
/etc/NetworkManager/system-connections/ens224.nmconnection