覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

CVE-2022-21449 が対象となるJavaバージョンはどれ?

Javaの脆弱性である CVE-2022-21449 が巷で話題・問題になってますが、


CVE-2022-21449は、ECDSA(楕円曲線デジタル署名アルゴリズム)のJavaの実装に欠陥があるため、不正なデジタル署名に対する検証が 誤って成功してしまう

というものです。


この脆弱性に関して、結局どの Java バージョンが影響を受けるのかについて、情報が錯綜しているようです。

ネットの情報の正しさを調べるのも面倒なので、どのJavaが影響を受けるのかはコードを書けば一応わかります。


検証用のコード

以下は、CVE-2022-21449が該当するJavaバージョンであるかを検証できるコードになります (IEEE P1363 の署名形式)

import java.security.*;

public class SignatureVerifyCheck {

    public static void main(String[] args) {
        // どのJava使ってるのか確認
        System.out.println(System.getProperty("java.vendor") + " : " + System.getProperty("java.version"));

        KeyPair keyPair;
        try {
            // Elliptic Curveアルゴリズムのキー・ペアを生成します。
            keyPair = KeyPairGenerator.getInstance("EC").generateKeyPair();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return;
        }
        System.out.println(keyPair);

        //  ECDSAシグネチャ・アルゴリズム(IEEE P1363 の署名形式)
        //  NONEwithECDSAinP1363Format / SHA1withECDSAinP1363Format / SHA224withECDSAinP1363Format /
        //  SHA256withECDSAinP1363Format / SHA384withECDSAinP1363Format / SHA512withECDSAinP1363Format
        Signature ecdsaSignature;
        try {
            ecdsaSignature = Signature.getInstance("SHA256withECDSAinP1363Format");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return;
        }
        System.out.println(ecdsaSignature);

        // 不正な署名の代わりとなる値
        byte[] blankSignature = new byte[64];

        try {
            // 署名オブジェクトを、検証操作のために指定された公開鍵で初期化します
            ecdsaSignature.initVerify(keyPair.getPublic());
            // 署名検証する対象をセットする
            ecdsaSignature.update("Hello, World".getBytes());

            // ※渡された署名を検証する。 署名が正しく検証されたなら true, そうでなければ false が返される  はずだが...
            boolean verifyResult = ecdsaSignature.verify(blankSignature);

            System.out.println("Invalid Signature verify result : " + verifyResult);  // ※不正な署名なら false となるはず
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (SignatureException e) {
            e.printStackTrace();
        }
    }
}

このコードの実行結果 で Invalid Signature verify result : true というものが出力されてしまうと、脆弱性の影響を受ける Java であることがわかります。


IEEE P1363 の署名形式 が使えない古いバージョンのJavaの場合以下の ASN.1 DER 署名形式を利用したコードで確認できます

import java.security.*;

public class SignatureVerifyCheck {

    public static void main(String[] args) {
        // どのJava使ってるのか確認
        System.out.println(System.getProperty("java.vendor") + " : " + System.getProperty("java.version"));

        KeyPair keyPair;
        try {
            // Elliptic Curveアルゴリズムのキー・ペアを生成します。
            keyPair = KeyPairGenerator.getInstance("EC").generateKeyPair();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return;
        }
        System.out.println(keyPair);

        // ECDSAシグネチャ・アルゴリズム (ASN.1 DER 署名)
        //  NONEwithECDSA / SHA1withECDSA / SHA224withECDSA /
        //  SHA256withECDSA / SHA384withECDSA / SHA512withECDSA ...
        Signature ecdsaSignature;
        try {
            ecdsaSignature = Signature.getInstance("SHA256withECDSA");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return;
        }
        System.out.println(ecdsaSignature);

        // 不正な署名の代わりとなる値 (ASN.1 DER 用)
        byte[] invalidSignature = new byte[]{ 0x30, 6, 2, 1, 0, 2, 1, 0 };
        
        try {
            // 署名オブジェクトを、検証操作のために指定された公開鍵で初期化します
            ecdsaSignature.initVerify(keyPair.getPublic());
            // 署名検証する対象をセットする
            ecdsaSignature.update("Hello, World".getBytes());

            // ※渡された署名を検証する。 署名が正しく検証されたなら true, そうでなければ false が返される  はずだが...
            boolean verifyResult = ecdsaSignature.verify(invalidSignature);

            System.out.println("Invalid Signature verify result : " + verifyResult);  // ※不正な署名なら false となるはず
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (SignatureException e) {
            e.printStackTrace();
        }
    }
}


いくつかのJavaで試した結果

いくつかの Java で実際に試してみて、結果がどうなるかを確認しました。


Eclipse Adoptium (AdoptOpenJDK) - 1.8.0_322

Temurin : 1.8.0_322
java.security.KeyPair@deb6432
Signature object: SHA256withECDSA<not initialized>
Invalid Signature verify result : false

最終的な結果が false となっているので 脆弱性の影響を受けません


Eclipse Adoptium (AdoptOpenJDK) - 11.0.14.1

Eclipse Adoptium : 11.0.14.1
java.security.KeyPair@371a67ec
Signature object: SHA256withECDSAinP1363Format<not initialized>
Invalid Signature verify result : false

最終的な結果が false となっているので 脆弱性の影響を受けません


Eclipse Adoptium (AdoptOpenJDK) - 17.0.2

Eclipse Adoptium : 17.0.2
java.security.KeyPair@7a79be86
Signature object: SHA256withECDSAinP1363Format<not initialized>
Invalid Signature verify result : true

最終的な結果が true となっているので 脆弱性の影響を受けます


Amazon corretto - 1.8.0_332

Amazon.com Inc. : 1.8.0_332
java.security.KeyPair@3581c5f3
Signature object: SHA256withECDSA<not initialized>
Invalid Signature verify result : false

最終的な結果が false となっているので 脆弱性の影響を受けません


Amazon corretto - 11.0.14.1

Amazon.com Inc. : 11.0.14.1
java.security.KeyPair@eafc191
Signature object: SHA256withECDSAinP1363Format<not initialized>
Invalid Signature verify result : false

最終的な結果が false となっているので 脆弱性の影響を受けません


Amazon corretto - 17.0.2

Amazon.com Inc. : 17.0.2
java.security.KeyPair@1d251891
Signature object: SHA256withECDSAinP1363Format<not initialized>
Invalid Signature verify result : true

最終的な結果が true となっているので 脆弱性の影響を受けます


Amazon corretto - 17.0.3

Amazon.com Inc. : 17.0.3
java.security.KeyPair@3f3afe78
Signature object: SHA256withECDSAinP1363Format<not initialized>
Invalid Signature verify result : false

最終的な結果が false となっているので 脆弱性の影響を受けません(脆弱性に対する修正が行われています)


Oracle OpenJDK - 17.0.2

Oracle Corporation : 17.0.2
java.security.KeyPair@2752f6e2
Signature object: SHA256withECDSAinP1363Format<not initialized>
Invalid Signature verify result : true

最終的な結果が true となっているので 脆弱性の影響を受けます


Oracle JDK - 1.7.0_80

Oracle Corporation : 1.7.0_80
java.security.KeyPair@60dd1773
Signature object: SHA256withECDSA<not initialized>
Invalid Signature verify result : false

最終的な結果が false となっているので 脆弱性の影響を受けません


Oracle JDK - 1.8.0_201

Oracle Corporation : 1.8.0_201
java.security.KeyPair@7daf6ecc
Signature object: SHA256withECDSA<not initialized>
Invalid Signature verify result : false

最終的な結果が false となっているので 脆弱性の影響を受けません


まとめ

いくつかの環境で脆弱性の影響を受けることが確認できました。

また、既に修正済みのバージョンや、そもそも対象の署名アルゴリズムが使えないバージョンも確認できました。


関連リンク

Files.lines(Path) 利用時は try-with-resources とともに利用する

久しぶりに Java 触ったときに何の悪気もなく以下のようなコードを書いてしまいました。

public class FilesTrial {

    public static void main(String[] args) throws IOException {
        Path path = Paths.get("/home/hogehoge/dummy.txt");

        Files.lines(path).forEach(line -> {
            String upperStr = line.toUpperCase(Locale.JAPAN);
            System.out.println(upperStr);
        });
}

実はこのコードだとStreamの元となっているIOリソースがクローズされません。
そのため、こういうコード書いちゃだめです。

忘れてました。。。


Files.lines(Path) を使うときは、try-with-resources で囲むという方法をとるのがよいです。

public class FilesTrial {

    public static void main(String[] args) throws IOException {
        Path path = Paths.get("/home/hogehoge/dummy.txt");

        // try-with-resources を使うのが正しい
        try (Stream<String> stream = Files.lines(path)) {
            stream.forEach(line -> {
                String upperStr = line.toUpperCase(Locale.JAPAN);
                System.out.println(upperStr);
            });
        }

    }
}

これにより Streamの元となっているIOリソースもクローズされます。



関連ページ

WSL版のAlmaLinux をインストールする

Windows の WSLで CentOS 代替 の Linux を使いたいなーと思っていたら、ちょうど以下のニュースリリースが出てました。


せっかくなので、Red Hat Enterprise Linux(RHEL)とのバイナリ互換がある AlmaLinux をWindows環境にインストールしてみました。


前提

WSLは利用可能な環境であることを前提としています。


AlmaLinux のインストール

WSLでAlmaLinux を利用するのは簡単で、Microsoft Store で AlmaLinux 8 WSL を入手すればよいです。


私は何となく winget でインストールしてみました。
winget install AlmaLinux を実行すれば AlmaLinux がインストールされます。


■実行結果

何かごちゃごちゃやってますが、 winget install AlmaLinux を PowerShell で実行すればよいです

PS C:\Users\ykiv> winget search AlmaLinux
名前            ID           バージョン ソース
------------------------------------------------
AlmaLinux 8 WSL 9NMD96XJJ19F Unknown    msstore
PS C:\Users\ykiv>
PS C:\Users\ykiv>
PS C:\Users\ykiv> winget show AlmaLinux
見つかりました AlmaLinux 8 WSL [9NMD96XJJ19F]
バージョン: Unknown
公開元: AlmaLinux OS Foundation
発行元 URL: https://almalinux.org
発行元のサポート URL: https://almalinux.org
説明: AlmaLinux OS comes to WSL! Now you can run all you favorite EL ecosystem applications, using the platform you know and love using all the standard tools, including dnf/yum, etc.

AlmaLinux is the Community Owned and Governed Enterprise-Grade Linux OS and is 1:1 RHEL and CentOS compatible.


ライセンス: ms-windows-store://pdp/?ProductId=9NMD96XJJ19F
プライバシー URL: https://almalinux.org/p/privacy-policy/
著作権: AlmaLinux OS Foundation
契約:
Category: Developer tools
Pricing: Free
Free Trial: No
Terms of Transaction: https://aka.ms/microsoft-store-terms-of-transaction
Seizure Warning: https://aka.ms/microsoft-store-seizure-warning
Store License Terms: https://aka.ms/microsoft-store-license

インストーラー:
  種類: msstore
  ストア製品 ID: 9NMD96XJJ19F
PS C:\Users\ykiv>
PS C:\Users\ykiv>
PS C:\Users\ykiv> winget install AlmaLinux
見つかりました AlmaLinux 8 WSL [9NMD96XJJ19F] バージョン Unknown
このパッケージは Microsoft Store から提供されています。winget は、現在のユーザーに代わって Microsoft Store からパッケー ジを取得する必要がある場合があります。
バージョン: Unknown
公開元: AlmaLinux OS Foundation
発行元 URL: https://almalinux.org
発行元のサポート URL: https://almalinux.org
説明: AlmaLinux OS comes to WSL! Now you can run all you favorite EL ecosystem applications, using the platform you know and love using all the standard tools, including dnf/yum, etc.

AlmaLinux is the Community Owned and Governed Enterprise-Grade Linux OS and is 1:1 RHEL and CentOS compatible.


ライセンス: ms-windows-store://pdp/?ProductId=9NMD96XJJ19F
プライバシー URL: https://almalinux.org/p/privacy-policy/
著作権: AlmaLinux OS Foundation
契約:
Category: Developer tools
Pricing: Free
Free Trial: No
Terms of Transaction: https://aka.ms/microsoft-store-terms-of-transaction
Seizure Warning: https://aka.ms/microsoft-store-seizure-warning
Store License Terms: https://aka.ms/microsoft-store-license


発行元は、お客様がインストール前に上記の情報を表示し、契約に同意することを必要としています。
使用条件に同意しますか?
[Y] はい  [N] いいえ: Y
パッケージ取得の確認/要求...
パッケージ取得の成功の確認/要求
パッケージのインストールを開始しています...
  ██████████████████████████████  100%
インストールが完了しました
PS C:\Users\ykiv>


インストールが完了したら AlmaLinux を起動します。
そうするとターミナルが起動するので、AlmaLinux を利用するために新規作成するユーザ(とパスワード)を入力します。


■実行結果

Installing, this may take a few minutes...
Please create a default UNIX user account. The username does not need to match your Windows username.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username: user-name
Changing password for user user-name.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
Installation successful!
[user-name@host-name:~]$

f:id:nini_y:20220409102301p:plain

これで WSL で利用可能となります。


f:id:nini_y:20220409102824p:plain

Windows Terminal にも AlmaLinux が追加されています。


OSの情報を見てみる

Windows Terminal で AlmaLinux を起動してOSの情報を少し確認してみました。

[~]$ uname -a
Linux host-name 5.10.102.1-microsoft-standard-WSL2 #1 SMP Wed Mar 2 00:30:59 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
[~]$
[~]$ cat /etc/redhat-release
AlmaLinux release 8.5 (Arctic Sphynx)
[~]$


ついでに neofetch もインストール してみました(以下コマンドを実行)。

sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

sudo dnf install epel-release

sudo dnf install neofetch


■実行結果

[~]$ sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
AlmaLinux 8 - BaseOS                                                                         4.3 MB/s | 7.0 MB     00:01
AlmaLinux 8 - AppStream                                                                      3.0 MB/s | 9.8 MB     00:03
AlmaLinux 8 - Extras                                                                          13 kB/s |  12 kB     00:00
(中略)
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                     1/1
  Installing       : epel-release-8-15.el8.noarch                                                                        1/1
  Running scriptlet: epel-release-8-15.el8.noarch                                                                        1/1
  Verifying        : epel-release-8-15.el8.noarch                                                                        1/1

Installed:
  epel-release-8-15.el8.noarch

Complete!
[~]$
[~]$ sudo dnf install epel-release
Extra Packages for Enterprise Linux 8 - x86_64                                               4.1 MB/s |  11 MB     00:02
Extra Packages for Enterprise Linux Modular 8 - x86_64                                       941 kB/s | 1.0 MB     00:01
Last metadata expiration check: 0:00:01 ago on Sat Apr  9 09:58:52 2022.
Package epel-release-8-15.el8.noarch is already installed.
Dependencies resolved.
Nothing to do.
Complete!
[~]$
[~]$ sudo dnf install neofetch
Last metadata expiration check: 0:00:50 ago on Sat Apr  9 09:58:52 2022.
Dependencies resolved.
(中略)
Installed size: 191 M
Is this ok [y/N]: y
Downloading Packages:
(1/129): avahi-libs-0.7-20.el8.x86_64.rpm                                                    711 kB/s |  61 kB     00:00
(中略)
(129/129): geolite2-city-20180605-1.el8.noarch.rpm                                           2.0 MB/s |  19 MB     00:09
-----------------------------------------------------------------------------------------------------------------------------
Total                                                                                        4.2 MB/s |  60 MB     00:14
Extra Packages for Enterprise Linux 8 - x86_64                                               1.6 MB/s | 1.6 kB     00:00
Importing GPG key 0x2F86D6A1:
 Userid     : "Fedora EPEL (8) <epel@fedoraproject.org>"
 Fingerprint: 94E2 79EB 8D8F 25B2 1810 ADF1 21EA 45AB 2F86 D6A1
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8
Is this ok [y/N]: y
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                     1/1
  Installing       : libpng-2:1.6.34-5.el8.x86_64                                                                      1/129
(中略)
  Verifying        : neofetch-7.1.0-6.el8.noarch                                                                     129/129

Installed:
  ImageMagick-6.9.10.86-1.el8.x86_64                        ImageMagick-libs-6.9.10.86-1.el8.x86_64
(中略)
  xorg-x11-utils-7.5-28.el8.x86_64

Complete!


neofetch の実行結果は以下の通りです

■実行結果

f:id:nini_y:20220409103542p:plain


まとめ

かなり簡単な手順で RHEL互換の AlmaLinux がWSLで利用できるようになりました。
CentOS の代替となる Linux が WSLで使えるようになってとても嬉しいです。



関連ページ・関連エントリ

AWS EC2インスタンスで L2TP/IPSec クライアントの設定をした際のメモ

思いっきり上記内容を参考にさせてもらって環境構築した際のメモです。


  • ここでは、Amazon Linux 2 AMI (HVM) - Kernel 4.14, SSD Volume Type - ami-09662e4f2b2fb67f9 を使用しています
  • EC2にElasticIPを割り当てている前提としています。


環境構築のための前準備

EPELリポジトリを追加

[ip-172-31-27-101 ~]$ sudo amazon-linux-extras install -y epel
Installing epel-release
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Cleaning repos: amzn2-core amzn2extra-docker amzn2extra-epel
12 metadata files removed
4 sqlite files removed
0 metadata files removed
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                                                                                                           | 3.7 kB  00:00:00     
amzn2extra-docker                                                                                                                    | 3.0 kB  00:00:00     
amzn2extra-epel                                                                                                                      | 3.0 kB  00:00:00     
(1/7): amzn2-core/2/x86_64/group_gz                                                                                                  | 2.5 kB  00:00:00     
(2/7): amzn2-core/2/x86_64/updateinfo                                                                                                | 452 kB  00:00:00     
(3/7): amzn2extra-epel/2/x86_64/primary_db                                                                                           | 1.8 kB  00:00:00     
(4/7): amzn2extra-docker/2/x86_64/updateinfo                                                                                         | 5.9 kB  00:00:00     
(5/7): amzn2extra-epel/2/x86_64/updateinfo                                                                                           |   76 B  00:00:00     
(6/7): amzn2extra-docker/2/x86_64/primary_db                                                                                         |  86 kB  00:00:00     
(7/7): amzn2-core/2/x86_64/primary_db                                                                                                |  60 MB  00:00:01     
Resolving Dependencies
--> Running transaction check
---> Package epel-release.noarch 0:7-11 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

============================================================================================================================================================
 Package                                 Arch                              Version                         Repository                                  Size
============================================================================================================================================================
Installing:
 epel-release                            noarch                            7-11                            amzn2extra-epel                             15 k

Transaction Summary
============================================================================================================================================================
Install  1 Package

Total download size: 15 k
Installed size: 24 k
Downloading packages:
epel-release-7-11.noarch.rpm                                                                                                         |  15 kB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : epel-release-7-11.noarch                                                                                                                 1/1 
  Verifying  : epel-release-7-11.noarch                                                                                                                 1/1 

Installed:
  epel-release.noarch 0:7-11                                                                                                                                

Complete!
  0  ansible2                 available    \
        [ =2.4.2  =2.4.6  =2.8  =stable ]

(省略)


libreswan xl2tpd をインストール

[ip-172-31-27-101 ~]$ sudo yum -y install libreswan xl2tpd
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
209 packages excluded due to repository priority protections
Resolving Dependencies
--> Running transaction check
---> Package libreswan.x86_64 0:3.25-4.8.amzn2.0.1 will be installed
--> Processing Dependency: unbound-libs >= 1.6.6 for package: libreswan-3.25-4.8.amzn2.0.1.x86_64
--> Processing Dependency: libunbound.so.2()(64bit) for package: libreswan-3.25-4.8.amzn2.0.1.x86_64
--> Processing Dependency: libldns.so.1()(64bit) for package: libreswan-3.25-4.8.amzn2.0.1.x86_64
---> Package xl2tpd.x86_64 0:1.3.15-1.el7 will be installed
--> Processing Dependency: ppp >= 2.4.5-18 for package: xl2tpd-1.3.15-1.el7.x86_64
--> Running transaction check
---> Package ldns.x86_64 0:1.6.16-10.amzn2.0.2 will be installed
---> Package ppp.x86_64 0:2.4.5-33.amzn2.0.3 will be installed
---> Package unbound-libs.x86_64 0:1.7.3-15.amzn2.0.4 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

(中略)
Installed:
  libreswan.x86_64 0:3.25-4.8.amzn2.0.1                                             xl2tpd.x86_64 0:1.3.15-1.el7                                            

Dependency Installed:
  ldns.x86_64 0:1.6.16-10.amzn2.0.2                 ppp.x86_64 0:2.4.5-33.amzn2.0.3                 unbound-libs.x86_64 0:1.7.3-15.amzn2.0.4                

Complete!


IPSec に関する環境構築

ipsec 再起動

[ip-172-31-27-101 ~]$ sudo systemctl restart ipsec


ipsec verify で [OK] となっていない項目を確認する

[ip-172-31-27-101 ~]$ ipsec verify
Verifying installed system and configuration files

Version check and ipsec on-path                         [OK]
Libreswan 3.25 (netkey) on 4.14.268-205.500.amzn2.x86_64
Checking for IPsec support in kernel                    [OK]
 NETKEY: Testing XFRM related proc values
         ICMP default/send_redirects                    [NOT DISABLED]

  Disable /proc/sys/net/ipv4/conf/*/send_redirects or NETKEY will act on or cause sending of bogus ICMP redirects!

         ICMP default/accept_redirects                  [NOT DISABLED]

  Disable /proc/sys/net/ipv4/conf/*/accept_redirects or NETKEY will act on or cause sending of bogus ICMP redirects!

         XFRM larval drop                               [OK]
Pluto ipsec.conf syntax                                 [OK]
Two or more interfaces found, checking IP forwarding    [FAILED]
Checking rp_filter                                      [ENABLED]
 /proc/sys/net/ipv4/conf/all/rp_filter                  [ENABLED]
 /proc/sys/net/ipv4/conf/default/rp_filter              [ENABLED]
 /proc/sys/net/ipv4/conf/eth0/rp_filter                 [ENABLED]
 /proc/sys/net/ipv4/conf/ip_vti0/rp_filter              [ENABLED]
  rp_filter is not fully aware of IPsec and should be disabled
Checking that pluto is running                          [OK]
 Pluto listening for IKE on udp 500                     [OK]
 Pluto listening for IKE/NAT-T on udp 4500              [OK]
 Pluto ipsec.secret syntax                              [UNKNOWN]
 (run ipsec verify as root to test ipsec.secrets)
Checking 'ip' command                                   [OK]
Checking 'iptables' command                             [OK]
Checking 'prelink' command does not interfere with FIPS [OK]
Checking for obsolete ipsec.conf options                [OBSOLETE KEYWORD]
problem with include filename '/etc/ipsec.d': Permission denied

ipsec verify: encountered 13 errors - see 'man ipsec_verify' for help


/etc/sysctl.conf へ以下を追記

# Disable /proc/sys/net/ipv4/conf/*/send_redirects
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.default.send_redirects=0
net.ipv4.conf.eth0.send_redirects=0
net.ipv4.conf.ip_vti0.send_redirects=0
net.ipv4.conf.lo.send_redirects=0 

# Disable /proc/sys/net/ipv4/conf/*/accept_redirects
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.eth0.accept_redirects=0
net.ipv4.conf.ip_vti0.accept_redirects=0
net.ipv4.conf.lo.accept_redirects=0

# Two or more interfaces found, checking IP forwarding    [FAILED]
net.ipv4.ip_forward=1

# Checking rp_filter
net.ipv4.conf.all.rp_filter=0
net.ipv4.conf.default.rp_filter=0
net.ipv4.conf.eth0.rp_filter=0
net.ipv4.conf.ip_vti0.rp_filter=0


sysctl -p で反映

[ip-172-31-27-101 ~]$ sudo sysctl -p
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.eth0.send_redirects = 0
net.ipv4.conf.ip_vti0.send_redirects = 0
net.ipv4.conf.lo.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.eth0.accept_redirects = 0
net.ipv4.conf.ip_vti0.accept_redirects = 0
net.ipv4.conf.lo.accept_redirects = 0
net.ipv4.ip_forward = 1
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.eth0.rp_filter = 0
net.ipv4.conf.ip_vti0.rp_filter = 0


空ファイルの /etc/ipsec.d/vpn.conf を作成

[ip-172-31-27-101 ~]$ sudo touch /etc/ipsec.d/vpn.conf


ipsec verify の結果がOKになっていることを確認する

[ip-172-31-27-101 ~]$ sudo ipsec verify
Verifying installed system and configuration files

Version check and ipsec on-path                         [OK]
Libreswan 3.25 (netkey) on 4.14.268-205.500.amzn2.x86_64
Checking for IPsec support in kernel                    [OK]
 NETKEY: Testing XFRM related proc values
         ICMP default/send_redirects                    [OK]
         ICMP default/accept_redirects                  [OK]
         XFRM larval drop                               [OK]
Pluto ipsec.conf syntax                                 [OK]
Two or more interfaces found, checking IP forwarding    [OK]
Checking rp_filter                                      [OK]
Checking that pluto is running                          [OK]
 Pluto listening for IKE on udp 500                     [OK]
 Pluto listening for IKE/NAT-T on udp 4500              [OK]
 Pluto ipsec.secret syntax                              [OK]
Checking 'ip' command                                   [OK]
Checking 'iptables' command                             [OK]
Checking 'prelink' command does not interfere with FIPS [OK]
Checking for obsolete ipsec.conf options                [OK]


/etc/ipsec.d/vpn.conf に設定を記述

conn L2TP
     authby=secret
     pfs=no
     auto=add
     keyingtries=3
     dpddelay=30
     dpdtimeout=120
     dpdaction=clear
     keyexchange=ike
     phase2=esp
     encapsulation=yes
     rekey=yes
     ikelifetime=1h
     keylife=1h
     type=transport
     left=%defaultroute
     leftid=<EC2インスタンスに紐づけたElasticIP>
     right=<接続先のVPNサーバのIPアドレス>
     rightid=<接続先のVPNサーバのプライベートIPアドレス>


/etc/ipsec.d/vpn.secrets に事前共有キーを記述

<EC2インスタンスに紐づけたElasticIP> <接続先のVPNサーバのプライベートIPアドレス> : PSK "<事前共有キー>"


ipsecを再起動してからIPSecの接続確立・ステータスの確認

[ip-172-31-27-101 ~]$ sudo systemctl restart ipsec
[ip-172-31-27-101 ~]$
[ip-172-31-27-101 ~]$ sudo ipsec auto --up L2TP
002 "L2TP" #1: initiating Main Mode
104 "L2TP" #1: STATE_MAIN_I1: initiate
106 "L2TP" #1: STATE_MAIN_I2: sent MI2, expecting MR2
108 "L2TP" #1: STATE_MAIN_I3: sent MI3, expecting MR3
(中略)
003 "L2TP" #2: Configured DPD (RFC 3706) support not enabled because remote peer did not advertise DPD support
004 "L2TP" #2: STATE_QUICK_I2: sent QI2, IPsec SA established transport mode {ESP/NAT=>0xaf309107 <0x68c3363a xfrm=AES_CBC_128-HMAC_SHA1_96 NATOA=xx.xx.xxx.xxx NATD=xxx.xx.xx.xx:4500 DPD=active}
[ip-172-31-27-101 ~]$
[ip-172-31-27-101 ~]$ sudo ipsec status
000 using kernel interface: netkey
000 interface lo/lo ::1@500
(中略)
000 "L2TP":   ESP algorithm newest: AES_CBC_128-HMAC_SHA1_96; pfsgroup=<N/A>
000  
000 Total IPsec connections: loaded 1, active 1
000  
000 State Information: DDoS cookies not required, Accepting new IKE connections
000 IKE SAs: total(1), half-open(0), open(0), authenticated(1), anonymous(0)
000 IPsec SAs: total(1), authenticated(1), anonymous(0)
000  
000 #1: "L2TP":4500 STATE_MAIN_I4 (ISAKMP SA established); EVENT_SA_REPLACE in 2562s; newest ISAKMP; nodpd; idle; import:admin initiate
000 #2: "L2TP":4500 STATE_QUICK_I2 (sent QI2, IPsec SA established); EVENT_SA_REPLACE in 2803s; newest IPSEC; eroute owner; isakmp#1; idle; import:admin initiate
000 #2: "L2TP" esp.af309107@xxx.xx.x.xxx esp.68c3363a@172.31.27.101 ref=0 refhim=0 Traffic: ESPin=0B ESPout=0B! ESPmax=4194303B 
000  
000 Bare Shunt list:
000

うまくいっていれば ipsec status の表示結果で active の値が1(以上)になる


L2TP (xl2tpd) に関する環境構築

/etc/xl2tpd/xl2tpd.conf の編集

  • [lns default] のセクションの設定値を; でコメントアウト
  • [lac L2TP] のセクションに関して下記の内容を追記
[lns default]
;ip range = 192.168.1.128-192.168.1.254
;local ip = 192.168.1.99
;require chap = yes
;refuse pap = yes
;require authentication = yes
;name = LinuxVPNserver
;ppp debug = yes
;pppoptfile = /etc/ppp/options.xl2tpd
;length bit = yes

[lac L2TP]
lns = <接続先のVPNサーバのIPアドレス>
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd.client
length bit = yes
autodial = yes
redial = yes
redial timeout = 10
max redials = 6


/etc/ppp/options.xl2tpd.client に以下の内容を記述する

user <接続用のユーザID>
debug
noauth
mtu 1280 <環境に合わせる>
mru 1280 <環境に合わせる>

/etc/ppp/chap-secrets に接続用のユーザID・パスワードを記述する

# Secrets for authentication using CHAP
# client        server  secret                  IP addresses
"<接続用のユーザID>"         *       "<接続用のパスワード>"      *


VPNクライアントでの接続

xl2tpd と ipsec を停止

[ip-172-31-27-101 ~]$ sudo systemctl stop xl2tpd && sudo systemctl stop ipsec


xl2tpd と ipsec を起動・接続確立

[ip-172-31-27-101 ~]$ sudo systemctl start ipsec && sudo systemctl start xl2tpd && sudo ipsec auto --up L2TP
002 "L2TP" #1: initiating Main Mode
104 "L2TP" #1: STATE_MAIN_I1: initiate
106 "L2TP" #1: STATE_MAIN_I2: sent MI2, expecting MR2
108 "L2TP" #1: STATE_MAIN_I3: sent MI3, expecting MR3
002 "L2TP" #1: Peer ID is ID_IPV4_ADDR: 'xx.x.x.x'
004 "L2TP" #1: STATE_MAIN_I4: ISAKMP SA established {auth=PRESHARED_KEY cipher=aes_256 integ=sha2_256 group=MODP2048}
003 "L2TP" #1: Configured DPD (RFC 3706) support not enabled because remote peer did not advertise DPD support
002 "L2TP" #2: initiating Quick Mode PSK+ENCRYPT+UP+IKEV1_ALLOW+IKEV2_ALLOW+SAREF_TRACK+IKE_FRAG_ALLOW+ESN_NO {using isakmp#1 msgid:3bfc33d8 proposal=defaults pfsgroup=no-pfs}
117 "L2TP" #2: STATE_QUICK_I1: initiate
003 "L2TP" #2: NAT-Traversal: received 2 NAT-OA. Using first, ignoring others
003 "L2TP" #2: Configured DPD (RFC 3706) support not enabled because remote peer did not advertise DPD support
(省略)


I/Fに(ifconfigの結果に) ppp0 が追加されていることを確認

[ip-172-31-27-101 ~]$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001
        inet 172-31-27-101  netmask 255.255.240.0  broadcast xxx.xx.xx.xxx
        inet6 fe80::4af:f7ff:fe9c:8a34  prefixlen 64  scopeid 0x20<link>
        ether 06:af:f7:9c:8a:34  txqueuelen 1000  (Ethernet)
        RX packets 42270  bytes 17254656 (16.4 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 44723  bytes 10391861 (9.9 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

(中略)

ppp0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1280
        inet xx.x.x.X  netmask 255.255.255.255  destination xx.x.x.x
        ppp  txqueuelen 3  (Point-to-Point Protocol)
        RX packets 7  bytes 67 (67.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 18  bytes 261 (261.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


route add で実際に通信したいIPアドレスへのスタティックルートを追加する (ppp0 経由で通信するように設定)

[ip-172-31-27-101 ~]$ sudo route add -net <通信したいIPアドレス> netmask 255.255.255.255 dev ppp0


接続したいIPアドレスへのping が通ることを確認 (ICMPに応答してくれる前提)

[ip-172-31-27-101 ~]$ ping -c 3 <通信したいIPアドレス>
PING xx.xxx.x.xx (xx.xxx.x.xx) 56(84) bytes of data.
64 bytes from xx.xxx.x.xx: icmp_seq=1 ttl=126 time=169 ms
64 bytes from xx.xxx.x.xx: icmp_seq=2 ttl=126 time=169 ms
64 bytes from xx.xxx.x.xx: icmp_seq=3 ttl=126 time=169 ms


これでVPN接続して、対象のIPアドレスへ通信ができる状態になっています


VPN切断

xl2tpd, ipsec を停止します

[ip-172-31-27-101 ~]$ sudo systemctl stop xl2tpd && sudo systemctl stop ipsec

これで、通信したいIPアドレスに対するrouteも消えます



参考にしたサイト・ページ

fsck.jp

psqlでnull を明示的に表示したい

Postgres の psql を使って SELECT の SQL を実行した場合に、対象のカラムの値が null なのか 空文字列なのか区別がつきにくいです。

そういった場合は、nullを明示的に分かりやすい文字列で表示する設定を行うのがよいです。


たとえば、値が null なら "(null)" と表示させる場合は psql で以下のように実行します。

\pset null (null)

こうすれば、null である部分は (null) と表示されるようになるので、視認性がよくなります。


ちなみに、psql 上で null がどのように表示されるかは SELECT null; を実行すればわかります。


■初期状態

db-001=# SELECT null;
 ?column?
----------

(1 row)


■\pset null (null) を実行した後の状態

db-001=# SELECT null;
 ?column?
----------
 (null)
(1 row)