0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Raspberry Pi 4 で NSSH (Non-Secure SHell) をビルドして Cipher/Mac の影響を測定する

Posted at

Motivation

  • Raspberry Pi 4 に Rockstor を Install してバックアップ取ってたら 20 [MB/s] とかで遅すぎた
  • top 見てたら sshd-session の CPU 使用率が 100% に張り付いていたので、暗号処理とか MAC 処理に苦しんでいるのでは?と
  • nc とか使えばいいじゃん、と思うかもしれないが、複数ファイルの処理とか、他の処理とのコンパチを考えると ssh を使えたほうが嬉しい
    • 個人的に ssh/scp/rsync をバックエンドにしてローカルキャッシュとかトランザクション処理を行う Python ライブラリを作っているので、その兼ね合いもある

TL;DR

OpenSSH のビルド

  • openssh-portable を DL して、「暗復号無効」「MAC 無効」のバイナリを作る

ソースの clone & checkout

% git clone https://github.com/openssh/openssh-portable
% cd openssh-portable
% git checkout V_9_9_P2
Note: switching to 'V_9_9_P2'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at d76b26751 autogenerated files for release

Ciphers "none" 有効化

% git apply enable-ciphers-none.patch
enable-ciphers-none.patch
diff --git a/cipher.c b/cipher.c
index 7d6e7d8c6..a98f6e81d 100644
--- a/cipher.c
+++ b/cipher.c
@@ -121,8 +121,8 @@ cipher_alg_list(char sep, int auth_only)
        const struct sshcipher *c;
 
        for (c = ciphers; c->name != NULL; c++) {
-               if ((c->flags & CFLAG_INTERNAL) != 0)
-                       continue;
+               //if ((c->flags & CFLAG_INTERNAL) != 0)
+               //      continue;
                if (auth_only && c->auth_len == 0)
                        continue;
                if (ret != NULL)
@@ -224,7 +224,7 @@ ciphers_valid(const char *names)
        for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
            (p = strsep(&cp, CIPHER_SEP))) {
                c = cipher_by_name(p);
-               if (c == NULL || (c->flags & CFLAG_INTERNAL) != 0) {
+               if (c == NULL) { //|| (c->flags & CFLAG_INTERNAL) != 0) {
                        free(cipher_list);
                        return 0;
                }
diff --git a/myproposal.h b/myproposal.h
index 3bdc2e955..d01704296 100644
--- a/myproposal.h
+++ b/myproposal.h
@@ -61,7 +61,8 @@
 #define        KEX_SERVER_ENCRYPT \
        "chacha20-poly1305@openssh.com," \
        "aes128-ctr,aes192-ctr,aes256-ctr," \
-       "aes128-gcm@openssh.com,aes256-gcm@openssh.com"
+       "aes128-gcm@openssh.com,aes256-gcm@openssh.com," \
+       "none"
 
 #define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT

MACs "none" 有効化

% git apply enable-mac-none.patch
enable-mac-none.patch
diff --git a/mac.c b/mac.c
index f3dda6692..45659f654 100644
--- a/mac.c
+++ b/mac.c
@@ -41,6 +41,7 @@
 
 #include "openbsd-compat/openssl-compat.h"
 
+#define SSH_NOMAC      -1      /* NO MAC */
 #define SSH_DIGEST     1       /* SSH_DIGEST_XXX */
 #define SSH_UMAC       2       /* UMAC (not integrated with OpenSSL) */
 #define SSH_UMAC128    3
@@ -76,6 +77,9 @@ static const struct macalg macs[] = {

+       /* NO MAC */
+       { "none",                               SSH_NOMAC, 0, 0, 0, 0, 0 },
+
        { NULL,                                 0, 0, 0, 0, 0, 0 }
 };
 
@@ -106,7 +110,12 @@ static int
 mac_setup_by_alg(struct sshmac *mac, const struct macalg *macalg)
 {
        mac->type = macalg->type;
-       if (mac->type == SSH_DIGEST) {
+       if (mac->type == SSH_NOMAC) {
+               mac->mac_len = 0;
+               mac->key_len = 0;
+               mac->hmac_ctx = NULL;
+               mac->umac_ctx = NULL;
+       } else if (mac->type == SSH_DIGEST) {
                if ((mac->hmac_ctx = ssh_hmac_start(macalg->alg)) == NULL)
                        return SSH_ERR_ALLOC_FAIL;
                mac->key_len = mac->mac_len = ssh_hmac_bytes(macalg->alg);
@@ -142,6 +151,8 @@ mac_init(struct sshmac *mac)
        if (mac->key == NULL)
                return SSH_ERR_INVALID_ARGUMENT;
        switch (mac->type) {
+       case SSH_NOMAC:
+               return 0;
        case SSH_DIGEST:
                if (mac->hmac_ctx == NULL ||
                    ssh_hmac_init(mac->hmac_ctx, mac->key, mac->key_len) < 0)
@@ -176,6 +187,9 @@ mac_compute(struct sshmac *mac, u_int32_t seqno,
                return SSH_ERR_INTERNAL_ERROR;
 
        switch (mac->type) {
+       case SSH_NOMAC:
+               memset(u.m, 0, sizeof(u.m));
+               break;
        case SSH_DIGEST:
                put_u32(b, seqno);
                /* reset HMAC context */
@@ -214,7 +228,9 @@ mac_check(struct sshmac *mac, u_int32_t seqno,
        u_char ourmac[SSH_DIGEST_MAX_LENGTH];
        int r;
 
-       if (mac->mac_len > mlen)
+       if (mac->type == SSH_NOMAC) {
+               return 0;
+       } else if (mac->mac_len > mlen)
                return SSH_ERR_INVALID_ARGUMENT;
        if ((r = mac_compute(mac, seqno, data, dlen,
            ourmac, sizeof(ourmac))) != 0)
diff --git a/myproposal.h b/myproposal.h
index 3bdc2e955..d01704296 100644
--- a/myproposal.h
+++ b/myproposal.h
@@ -75,7 +76,8 @@
        "umac-128@openssh.com," \
        "hmac-sha2-256," \
        "hmac-sha2-512," \
-       "hmac-sha1"
+       "hmac-sha1," \
+       "none"
 
 #define KEX_CLIENT_MAC KEX_SERVER_MAC

sshd_config 編集 (listen port)

  • 2222 番ポートで起動するように設定
% git apply listen-on-2222.patch
% grep "Port " sshd_config
Port 2222
listen-on-2222.patch
diff --git a/sshd_config b/sshd_config
index 36894ace5..24620675a 100644
--- a/sshd_config
+++ b/sshd_config
@@ -10,7 +10,7 @@
 # possible, but leave them commented.  Uncommented options override the
 # default value.
 
-#Port 22
+Port 2222
 #AddressFamily any
 #ListenAddress 0.0.0.0
 #ListenAddress ::

ビルド

git diff
diff --git a/cipher.c b/cipher.c
index 7d6e7d8c6..a98f6e81d 100644
--- a/cipher.c
+++ b/cipher.c
@@ -121,8 +121,8 @@ cipher_alg_list(char sep, int auth_only)
        const struct sshcipher *c;
 
        for (c = ciphers; c->name != NULL; c++) {
-               if ((c->flags & CFLAG_INTERNAL) != 0)
-                       continue;
+               //if ((c->flags & CFLAG_INTERNAL) != 0)
+               //      continue;
                if (auth_only && c->auth_len == 0)
                        continue;
                if (ret != NULL)
@@ -224,7 +224,7 @@ ciphers_valid(const char *names)
        for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
            (p = strsep(&cp, CIPHER_SEP))) {
                c = cipher_by_name(p);
-               if (c == NULL || (c->flags & CFLAG_INTERNAL) != 0) {
+               if (c == NULL) { //|| (c->flags & CFLAG_INTERNAL) != 0) {
                        free(cipher_list);
                        return 0;
                }
diff --git a/mac.c b/mac.c
index f3dda6692..45659f654 100644
--- a/mac.c
+++ b/mac.c
@@ -41,6 +41,7 @@
 
 #include "openbsd-compat/openssl-compat.h"
 
+#define SSH_NOMAC      -1      /* NO MAC */
 #define SSH_DIGEST     1       /* SSH_DIGEST_XXX */
 #define SSH_UMAC       2       /* UMAC (not integrated with OpenSSL) */
 #define SSH_UMAC128    3
@@ -76,6 +77,9 @@ static const struct macalg macs[] = {
        { "umac-64-etm@openssh.com",            SSH_UMAC, 0, 0, 128, 64, 1 },
        { "umac-128-etm@openssh.com",           SSH_UMAC128, 0, 0, 128, 128, 1 },
 
+       /* NO MAC */
+       { "none",                               SSH_NOMAC, 0, 0, 0, 0, 0 },
+
        { NULL,                                 0, 0, 0, 0, 0, 0 }
 };
 
@@ -106,7 +110,12 @@ static int
 mac_setup_by_alg(struct sshmac *mac, const struct macalg *macalg)
 {
        mac->type = macalg->type;
-       if (mac->type == SSH_DIGEST) {
+       if (mac->type == SSH_NOMAC) {
+               mac->mac_len = 0;
+               mac->key_len = 0;
+               mac->hmac_ctx = NULL;
+               mac->umac_ctx = NULL;
+       } else if (mac->type == SSH_DIGEST) {
                if ((mac->hmac_ctx = ssh_hmac_start(macalg->alg)) == NULL)
                        return SSH_ERR_ALLOC_FAIL;
                mac->key_len = mac->mac_len = ssh_hmac_bytes(macalg->alg);
@@ -142,6 +151,8 @@ mac_init(struct sshmac *mac)
        if (mac->key == NULL)
                return SSH_ERR_INVALID_ARGUMENT;
        switch (mac->type) {
+       case SSH_NOMAC:
+               return 0;       
        case SSH_DIGEST:
                if (mac->hmac_ctx == NULL ||
                    ssh_hmac_init(mac->hmac_ctx, mac->key, mac->key_len) < 0)
@@ -176,6 +187,9 @@ mac_compute(struct sshmac *mac, u_int32_t seqno,
                return SSH_ERR_INTERNAL_ERROR;
 
        switch (mac->type) {
+       case SSH_NOMAC:
+               memset(u.m, 0, sizeof(u.m));
+               break;
        case SSH_DIGEST:
                put_u32(b, seqno);
                /* reset HMAC context */
@@ -214,7 +228,9 @@ mac_check(struct sshmac *mac, u_int32_t seqno,
        u_char ourmac[SSH_DIGEST_MAX_LENGTH];
        int r;
 
-       if (mac->mac_len > mlen)
+       if (mac->type == SSH_NOMAC) {
+               return 0;
+       } else if (mac->mac_len > mlen)
                return SSH_ERR_INVALID_ARGUMENT;
        if ((r = mac_compute(mac, seqno, data, dlen,
            ourmac, sizeof(ourmac))) != 0)
diff --git a/myproposal.h b/myproposal.h
index 3bdc2e955..d01704296 100644
--- a/myproposal.h
+++ b/myproposal.h
@@ -61,7 +61,8 @@
 #define        KEX_SERVER_ENCRYPT \
        "chacha20-poly1305@openssh.com," \
        "aes128-ctr,aes192-ctr,aes256-ctr," \
-       "aes128-gcm@openssh.com,aes256-gcm@openssh.com"
+       "aes128-gcm@openssh.com,aes256-gcm@openssh.com," \
+       "none"
 
 #define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT
 
@@ -75,7 +76,8 @@
        "umac-128@openssh.com," \
        "hmac-sha2-256," \
        "hmac-sha2-512," \
-       "hmac-sha1"
+       "hmac-sha1," \
+       "none"
 
 #define KEX_CLIENT_MAC KEX_SERVER_MAC
 
diff --git a/sshd_config b/sshd_config
index 36894ace5..24620675a 100644
--- a/sshd_config
+++ b/sshd_config
@@ -10,7 +10,7 @@
 # possible, but leave them commented.  Uncommented options override the
 # default value.
 
-#Port 22
+Port 2222
 #AddressFamily any
 #ListenAddress 0.0.0.0
 #ListenAddress ::
% sudo apt install automake autoconf libssl-dev

% INSTALLDIR=/opt/nssh
% sudo rm -rf ${INSTALLDIR}
% sudo mkdir -p ${INSTALLDIR}
% autoreconf
% ./configure --prefix=${INSTALLDIR}
% make
% sudo make install
% tree /opt/nssh
/opt/nssh
├── bin
│   ├── scp
│   ├── sftp
│   ├── ssh
│   ├── ssh-add
│   ├── ssh-agent
│   ├── ssh-keygen
│   └── ssh-keyscan
├── etc
│   ├── moduli
│   ├── ssh_config
│   ├── ssh_host_ecdsa_key
│   ├── ssh_host_ecdsa_key.pub
│   ├── ssh_host_ed25519_key
│   ├── ssh_host_ed25519_key.pub
│   ├── ssh_host_rsa_key
│   ├── ssh_host_rsa_key.pub
│   └── sshd_config
├── lib
│   ├── sftp-server
│   ├── ssh-keysign
│   ├── ssh-pkcs11-helper
│   ├── ssh-sk-helper
│   └── sshd-session
├── sbin
│   └── sshd
└── share
    └── man
        ├── cat1
        │   ├── scp.1
        │   ├── sftp.1
        │   ├── ssh-add.1
        │   ├── ssh-agent.1
        │   ├── ssh-keygen.1
        │   ├── ssh-keyscan.1
        │   └── ssh.1
        ├── cat5
        │   ├── moduli.5
        │   ├── ssh_config.5
        │   └── sshd_config.5
        └── cat8
            ├── sftp-server.8
            ├── ssh-keysign.8
            ├── ssh-pkcs11-helper.8
            ├── ssh-sk-helper.8
            └── sshd.8

9 directories, 37 files

sshd 起動

  • sshd は絶対パスで指定される必要アリ
% sudo /opt/nssh/sbin/sshd -f /opt/nssh/etc/sshd_config

性能測定

  • サーバ側 $
    • Raspberry Pi4 / 8GB
    • nssh (openssh-portable V_9_9_P2)
  • クライアント側 %
    • NUC8i3BEH
    • nssh (openssh-portable V_9_9_P2)
  • 計測コマンド
% dd if=/dev/random of=/tmp/in.img bs=4K count=512K
% cat /tmp/in.img | /opt/nssh/bin/ssh -c <cipher> -m <mac> -p 2222 rpi4 'dd of=/dev/null'
  • 計測結果

graph.jpg

cipher mac Throughput (min) [MB/s] Throughput (mean) [MB/s] Throughput (MAX) [MB/s]
aes128-ctr hmac-sha1 45.2 50.08 60.9
aes128-ctr hmac-sha2-256 46.0 49.02 51.3
aes128-ctr hmac-sha2-512 48.3 55.58 60.8
aes128-ctr umac-64@openssh.com 66.5 73.18 77.7
aes128-ctr umac-128@openssh.com 60.2 70.92 77.7
aes128-ctr hmac-sha1-etm@openssh.com 50.1 54.94 60.5
aes128-ctr hmac-sha2-256-etm@openssh.com 42.7 47.66 54.9
aes128-ctr hmac-sha2-512-etm@openssh.com 52.6 56.9 60.6
aes128-ctr umac-64-etm@openssh.com 68.0 77.6 81.2
aes128-ctr umac-128-etm@openssh.com 59.4 73.78 79.6
aes128-ctr none 81.3 83.62 85.0
aes192-ctr hmac-sha1 50.0 54.68 56.8
aes192-ctr hmac-sha2-256 46.1 48.98 51.3
aes192-ctr hmac-sha2-512 43.2 50.12 55.4
aes192-ctr umac-64@openssh.com 64.8 69.32 72.6
aes192-ctr umac-128@openssh.com 64.8 67.46 69.4
aes192-ctr hmac-sha1-etm@openssh.com 49.0 52.58 56.4
aes192-ctr hmac-sha2-256-etm@openssh.com 43.8 47.7 51.0
aes192-ctr hmac-sha2-512-etm@openssh.com 52.9 54.12 55.5
aes192-ctr umac-64-etm@openssh.com 60.5 65.96 70.8
aes192-ctr umac-128-etm@openssh.com 54.3 64.08 69.1
aes192-ctr none 70.0 73.82 75.8
aes256-ctr hmac-sha1 48.2 49 50.4
aes256-ctr hmac-sha2-256 43.0 44.18 45.5
aes256-ctr hmac-sha2-512 44.3 50.7 54.7
aes256-ctr umac-64@openssh.com 50.7 57.6 63.4
aes256-ctr umac-128@openssh.com 58.5 61.48 63.8
aes256-ctr hmac-sha1-etm@openssh.com 44.9 48.86 50.7
aes256-ctr hmac-sha2-256-etm@openssh.com 37.7 43.66 47.6
aes256-ctr hmac-sha2-512-etm@openssh.com 47.7 49.78 51.6
aes256-ctr umac-64-etm@openssh.com 54.5 59.54 63.0
aes256-ctr umac-128-etm@openssh.com 57.1 59.4 63.5
aes256-ctr none 59.3 63.16 66.7
aes128-gcm@openssh.com hmac-sha1 46.8 48.36 50.2
aes128-gcm@openssh.com hmac-sha2-256 45.6 48.74 51.1
aes128-gcm@openssh.com hmac-sha2-512 48.8 49.72 50.4
aes128-gcm@openssh.com umac-64@openssh.com 48.0 48.82 50.5
aes128-gcm@openssh.com umac-128@openssh.com 46.7 49.22 50.6
aes128-gcm@openssh.com hmac-sha1-etm@openssh.com 46.6 48.54 49.9
aes128-gcm@openssh.com hmac-sha2-256-etm@openssh.com 44.8 48.94 50.3
aes128-gcm@openssh.com hmac-sha2-512-etm@openssh.com 46.9 48.5 49.5
aes128-gcm@openssh.com umac-64-etm@openssh.com 40.6 47.18 50.7
aes128-gcm@openssh.com umac-128-etm@openssh.com 48.1 49.24 50.3
aes128-gcm@openssh.com none 45.0 47.86 50.4
aes256-gcm@openssh.com hmac-sha1 41.9 43.24 44.1
aes256-gcm@openssh.com hmac-sha2-256 42.8 43.9 44.7
aes256-gcm@openssh.com hmac-sha2-512 40.7 42.36 43.8
aes256-gcm@openssh.com umac-64@openssh.com 40.5 42.66 44.3
aes256-gcm@openssh.com umac-128@openssh.com 41.3 43.2 44.1
aes256-gcm@openssh.com hmac-sha1-etm@openssh.com 42.0 43.46 44.4
aes256-gcm@openssh.com hmac-sha2-256-etm@openssh.com 40.9 43.2 44.4
aes256-gcm@openssh.com hmac-sha2-512-etm@openssh.com 40.8 42.7 44.4
aes256-gcm@openssh.com umac-64-etm@openssh.com 40.1 42.5 44.5
aes256-gcm@openssh.com umac-128-etm@openssh.com 41.4 43.64 44.8
aes256-gcm@openssh.com none 39.0 42.42 44.9
chacha20-poly1305@openssh.com hmac-sha1 76.5 84.44 97.2
chacha20-poly1305@openssh.com hmac-sha2-256 77.1 81.52 87.3
chacha20-poly1305@openssh.com hmac-sha2-512 75.2 85.4 94.3
chacha20-poly1305@openssh.com umac-64@openssh.com 78.1 89.14 102
chacha20-poly1305@openssh.com umac-128@openssh.com 74.4 81.3 95.3
chacha20-poly1305@openssh.com hmac-sha1-etm@openssh.com 79.8 84.22 92.2
chacha20-poly1305@openssh.com hmac-sha2-256-etm@openssh.com 79.6 85.44 89.7
chacha20-poly1305@openssh.com hmac-sha2-512-etm@openssh.com 72.6 78.94 83.5
chacha20-poly1305@openssh.com umac-64-etm@openssh.com 74.7 83.08 89.7
chacha20-poly1305@openssh.com umac-128-etm@openssh.com 75.7 83.02 89.9
chacha20-poly1305@openssh.com none 78.8 83.22 85.7
none hmac-sha1 88.0 99.12 111
none hmac-sha2-256 82.1 89.64 94.1
none hmac-sha2-512 75.7 81.28 96.5
none umac-64@openssh.com 89.1 93.52 95.7
none umac-128@openssh.com 88.4 92.04 95.8
none hmac-sha1-etm@openssh.com 91.9 98.8 103
none hmac-sha2-256-etm@openssh.com 76.6 90.48 95.0
none hmac-sha2-512-etm@openssh.com 77.7 80.82 82.9
none umac-64-etm@openssh.com 87.2 91.08 95.2
none umac-128-etm@openssh.com 90.2 92.96 100
none none 95.4 102.84 113
0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?