MySQLのCheat Sheet

rootでログイン

mysql -u root -p

パスワードのアップデート

mysql> use mysql
Database changed

mysql>UPDATE user SET authentication_string=password('newpwd')
 -> WHERE User = 'root';
mysql> FLUSH PRIVILEGES;

パスワードのセキュリティレベル

mysql> SHOW VARIABLES LIKE 'validate_password%';
mysql> SET GLOBAL validate_password_length=6;
mysql> SET GLOBAL validate_password_policy=LOW;
mysql> SHOW VARIABLES LIKE 'validate_password%';
mysql> SET PASSWORD FOR 'root'@'localhost'=password('root');

匿名アカウントのパスワードの割り当て

mysql> SET PASSWORD FOR ''@'localhost' = PASSWORD('newpwd');
mysql> SET PASSWORD FOR ''@'host_name' = PASSWORD('newpwd');
mysql> FLUSH PRIVILEGES;

匿名アカウントの削除

mysql> DROP USER ''@'localhost';
mysql> DROP USER ''@'{host}';

ユーザーの確認

mysql> SELECT user,host FROM mysql.user;

存在するデータベースの一覧を確認

mysql> SHOW DATABASES;

外部ホストからの接続を許可する

mysql> GRANT ALL PRIVILEGES ON client_data.* TO '{user}'@'{host}' identified by '{password}' WITH GRANT OPTION;

すべてのホストから接続できるようにする

mysql> GRANT ALL PRIVILEGES ON client_data.* TO '{user}'@'%' IDENTIFIED BY '{password}' WITH GRANT OPTION;

LANのすべてのホストから接続できるように設定する

例)ネットワーク:192.168.1.0/24

mysql> GRANT ALL PRIVILEGES ON client_data.* TO '{user}'@'192.168.1.%' IDENTIFIED BY '{password}' WITH GRANT OPTION;

外部ホストからのログイン

mysql -h {host} -u {user} -p

ユーザ作成

mysql> GRANT ALL PRIVILEGES ON *.* TO 'user'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
mysql> GRANT ALL PRIVILEGES ON {db_name}.* TO 'user'@localhost IDENTIFIED BY 'password' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
mysql> GRANT ALL PRIVILEGES ON *.* TO 'user'@localhost IDENTIFIED BY 'password';
mysql> FLUSH PRIVILEGES;
mysql> GRANT ALL PRIVILEGES ON {db_name}.* TO 'user'@'localhost' IDENTIFIED BY 'password';
mysql> FLUSH PRIVILEGES;
mysql> GRANT SELECT,INSERT,UPDATE,DELETE ON *.* TO 'user'@'localhost' IDENTIFIED BY 'password';
mysql> FLUSH PRIVILEGES;
mysql> GRANT SELECT,INSERT,UPDATE,DELETE ON {db_name}.* TO 'user'@'localhost' IDENTIFIED BY 'パスワード';
mysql> FLUSH PRIVILEGES;

権限追加

mysql> GRANT CREATE ON {db_name}.* TO 'user'@'localhost';
mysql> GRANT DROP ON {db_name}.* TO 'user'@'localhost';
mysql> GRANT ALTER ON {db_name}.* TO 'user'@'localhost';

権限の確認

mysql> SHOW GRANTS FOR 'user'@'localhost' \G

権限の削除

mysql> REVOKE ALL PRIVILEGES ON *.* FROM 'user'@'localhost';
mysql> REVOKE 削除する権限 ON {db_name.*} FROM 'user';

データーベースの作成

mysql> CREATE DATABASE {db_name};
mysql> SHOW WARNINGS;

データベースへ接続

mysql> USE {db_name};

接続しているデータベースの確認

mysql> SELECT DATABASE();
mysql> SHOW DATABASES;

例)テーブルの作成

CREATE TABLE chart_1d (timestamp INT UNSIGNED NOT NULL UNIQUE, open FLOAT NOT NULL, high FLOAT NOT NULL, low FLOAT NOT NULL, close FLOAT NOT NULL, volume FLOAT NOT NULL);

フィールドの確認

DESCRIBE {table_name};
SELECT * FROM {table_name};

コラムの変更

MariaDB [Binance]> alter table chart_1d change Unixtime timestamp INT UNSIGNED NOT NULL UNIQUE;
MariaDB [Binance]> alter table chart_1d change High high FLOAT NOT NULL;

データベースを削除

mysql> DROP DATABASE {db_name};

テーブルを削除

mysql> DROP TABLE {table_name};

 データベースのセキュリティー設定:

例)テスト

mysql> DELETE FROM mysql.db WHERE Db LIKE 'test%';
mysql> FLUSH PRIVILEGES;
mysql> DROP DATABASE test;

パスワードポリシーの変更

SET GLOBAL validate_password_policy=MEDIUM;

Backup

mysqldump -u root -p {DB name} > {DB name}.sql

Backup:既存のデータベースを上書きする場合

mysqldump -u root -p --add-drop-table {DB name} > {DB name}.sql

Restore

mysql -u root -p {DB name} < {DB name}.sql

CSVファイルのインポート

mysqlimport --ignore-lines=1\
             --fields-terminated-by=,\
             --local -u root -p\
             Binance \
             ${csvfile}

Nginxを使ってWord Pressをセットアップ

Nginxは近年、人気が出てきたWebサーバで、軽量でかつ設定を冗長に出来るのが人気に秘密です。今回、次のような構成で設定してみることにしました。リバースプロキシに3台のウェブサーバを繋いでみます。

Internet <--> Reverse Proxy: Nginx <--> Web Servers: Nginx + Word Press

VPSにLXCを導入したのでプライベートネットワーク化して、SQLサーバなど個々にサーバを立てることができるようになっています。各設定は検索するとかなりの数がヒットするのでここでは設定例に留めておきます。

設定例: Reverse Proxy

Nginx

/etc/nginx/sites-enabled:

server { 
    listen       80; 
    server_name   www.example.net; 
    return 301    https://$host$request_uri; 
} 
 
server { 
    listen       80; 
    server_name   mail.example.net; 
    return 301    https://$host$request_uri; 
} 
 
server { 
    listen       443 ssl; 
    server_name www.example.net; 
 
    root /var/www/html; 
    index index.php index.html index.nginx-debian.html; 
 
    proxy_set_header    X-Real-IP       $remote_addr; 
    proxy_set_header    Host            $host; 
    proxy_set_header    X-Forwarded-Proto $scheme; 
    proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for; 
 
ssl_certificate /etc/letsencrypt/live/example.net/fullchain.pem; # managed by Certbot 
ssl_certificate_key /etc/letsencrypt/live/example.net/privkey.pem; # managed by Certbot 
 
    ssl_session_cache  builtin:1000  shared:SSL:10m; 
#    ssl_session_cache shared:SSL:10m; 
#    ssl_session_timeout  5m; 
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE
-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDH
E-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:D
HE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:
AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DE
S-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; 
    ssl_prefer_server_ciphers   on; 
    ssl_dhparam /etc/nginx/ssl/dhparams.pem; 
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
 
 #   if ($scheme != "https") { 
 #       return 301 https://$host$request_uri; 
 #   } # managed by Certbot 
    location / { 
        proxy_pass http://10.0.0.2; 
        proxy_read_timeout  240; 
        proxy_buffering     off; 
        proxy_redirect      off; 
 
    } 
    location /OpenWrt { 
        proxy_pass http://10.0.0.3; 
        proxy_read_timeout  240; 
        proxy_buffering     off; 
        proxy_redirect      off; 
    } 
    location  { 
        proxy_pass http://10.0.0.4; 
        limit_req   zone=one  burst=1 nodelay; 
        proxy_read_timeout  240; 
        proxy_buffering     off; 
        proxy_redirect      off; 
    } 
    location ~ ^/\.user\.ini { 
        deny all; 
    } 
    location ~ ^/OpenWrt/\.user\.ini { 
        deny all; 
    } 
    location ~ ^/\.user\.ini { 
        deny all; 
    } 
    location ~ /.well-known/acme-challenge { 
        allow all; 
    } 
} 
 
server { 
    listen       443 ssl; 
    server_name  mail.example.net; 
 
    proxy_set_header    X-Real-IP       $remote_addr; 
    proxy_set_header    Host            $host; 
    proxy_set_header    X-Forwarded-Proto $scheme; 
    proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;  
    proxy_read_timeout  240; 
    proxy_buffering     off; 
 
ssl_certificate /etc/letsencrypt/live/example.net/fullchain.pem; # managed by Certbot 
ssl_certificate_key /etc/letsencrypt/live/example.net/privkey.pem; # managed by Certbot 
 
    ssl_session_cache  builtin:1000  shared:SSL:10m; 
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE
-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDH
E-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:D
HE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:
AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DE
S-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; 
    ssl_prefer_server_ciphers   on; 
    ssl_dhparam /etc/nginx/ssl/dhparams.pem; 
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
 
    location / { 
        proxy_pass http://10.0.0.5; 
        proxy_redirect      http://10.0.0.5 http://10.0.0.5/webmail; 
    } 
}

DH Groupの作成

$ sudo openssl dhparam -out dhparams.pem 2048

 Nginx

/etc/nginx/sites-enabled:

server { 
        listen       80; 
        server_name  www.example.net; 
        index index.php ; 
        root /var/www/wordpress; 
        location ~* /wp-config.php { 
             deny all; 
        } 
        location ~ \.php$ { 
         
                root            /var/www/wordpress ; 
                fastcgi_index index.php; 
                fastcgi_param HTTPS           $https if_not_empty; 
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 
                include        fastcgi_params; 
                fastcgi_pass unix:/run/php/php7.0-fpm.sock; 
        } 
        location ~ ^/\.user\.ini { 
                deny all; 
        } 
        location @webapp { 
                fastcgi_pass   unix:/run/php/php7.0-fpm.sock; 
                fastcgi_param   SCRIPT_FILENAME /var/www/wordpress/index.php; 
                include /etc/nginx/fastcgi_params; 
        } 
}

PHP: FastCGI

インストール

$ sudo apt install php-cli php-common php-fpm php-gd \
$ sudo php-json php-mysql php-opcache php-readline

/etc/php/7.0/fpm/php.ini:

[PHP] 
engine = On 
short_open_tag = Off 
precision = 14 
output_buffering = 4096 
zlib.output_compression = Off 
implicit_flush = Off 
unserialize_callback_func = 
serialize_precision = 17 
disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wi
fsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispat
ch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcnt
l_getpriority,pcntl_setpriority, 
disable_classes = 
zend.enable_gc = On 
expose_php = Off 
max_execution_time = 30 
max_input_time = 60 
memory_limit = 128M 
max_input_vars = 5000 
max_execution_time = 300 
post_max_size = 50M 
upload_max_filesize = 50M 
suhosin.request.max_vars = 5000 
suhosin.post.max_vars = 5000 
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT 
display_errors = Off 
display_startup_errors = Off 
log_errors = On 
log_errors_max_len = 1024 
ignore_repeated_errors = Off 
ignore_repeated_source = Off 
report_memleaks = On 
track_errors = Off 
html_errors = On 
variables_order = "GPCS" 
request_order = "GP" 
register_argc_argv = Off 
auto_globals_jit = On 
post_max_size = 8M 
auto_prepend_file = 
auto_append_file = 
default_mimetype = "text/html" 
default_charset = "UTF-8" 
doc_root = 
user_dir = 
enable_dl = Off 
file_uploads = On 
upload_max_filesize = 2M 
max_file_uploads = 20 
allow_url_fopen = On 
allow_url_include = Off 
default_socket_timeout = 60 
[CLI Server] 
cli_server.color = On 
[Date] 
[filter] 
[iconv] 
[intl] 
[sqlite3] 
[Pcre] 
[Pdo] 
[Pdo_mysql] 
pdo_mysql.cache_size = 2000 
pdo_mysql.default_socket= 
[Phar] 
[mail function] 
SMTP = localhost 
smtp_port = 25 
mail.add_x_header = On 
[SQL] 
sql.safe_mode = Off 
[ODBC] 
odbc.allow_persistent = On 
odbc.check_persistent = On 
odbc.max_persistent = -1 
odbc.max_links = -1 
odbc.defaultlrl = 4096 
odbc.defaultbinmode = 1 
[Interbase] 
ibase.allow_persistent = 1 
ibase.max_persistent = -1 
ibase.max_links = -1 
ibase.timestampformat = "%Y-%m-%d %H:%M:%S" 
ibase.dateformat = "%Y-%m-%d" 
ibase.timeformat = "%H:%M:%S" 
[MySQLi] 
mysqli.max_persistent = -1 
mysqli.allow_persistent = On 
mysqli.max_links = -1 
mysqli.cache_size = 2000 
mysqli.default_port = 3306 
mysqli.default_socket = 
mysqli.default_host = 
mysqli.default_user = 
mysqli.default_pw = 
mysqli.reconnect = Off 
[mysqlnd] 
mysqlnd.collect_statistics = On 
mysqlnd.collect_memory_statistics = Off 
[OCI8] 
[PostgreSQL] 
pgsql.allow_persistent = On 
pgsql.auto_reset_persistent = Off 
pgsql.max_persistent = -1 
pgsql.max_links = -1 
pgsql.ignore_notice = 0 
pgsql.log_notice = 0 
[bcmath] 
bcmath.scale = 0 
[browscap] 
[Session] 
session.save_handler = files 
session.use_strict_mode = 0 
session.use_cookies = 1 
session.use_only_cookies = 1 
session.name = PHPSESSID 
session.auto_start = 0 
session.cookie_lifetime = 0 
session.cookie_path = / 
session.cookie_domain = 
session.cookie_httponly = 
session.serialize_handler = php 
session.gc_probability = 0 
session.gc_divisor = 1000 
session.gc_maxlifetime = 1440 
session.referer_check = 
session.cache_limiter = nocache 
session.cache_expire = 180 
session.use_trans_sid = 0 
session.hash_function = 0 
session.hash_bits_per_character = 5 
url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" 
[Assertion] 
zend.assertions = -1 
[COM] 
[mbstring] 
[gd] 
[exif] 
[Tidy] 
tidy.clean_output = Off 
[soap] 
soap.wsdl_cache_enabled=1 
soap.wsdl_cache_dir="/tmp" 
soap.wsdl_cache_ttl=86400 
soap.wsdl_cache_limit = 5 
[sysvshm] 
[ldap] 
ldap.max_links = -1 
[mcrypt] 
[dba] 
[opcache] 
[curl] 
[openssl]

WordPress

SSL用に追加します。

/var/www/wordpress/wp-config.php:

/** 
 * Handle SSL reverse proxy 
 */
 if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') 
    $_SERVER['HTTPS']='on'; 
 
if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) { 
    $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST']; 
}

 

 

Mail Server: PostfixとDovecotを使ったメールサーバの構築

PostfixとDovecotを使ったメールサーバはポピュラーなので、サイトを検索するといくつか設定方法がヒットしますが、ある程度セキュリティを取り入れた設定となるとあまり実例が見つかりません。そのなかで、分かりやすかったサイトがあったのでそれを参考に構築してみました。

SSL/TLSでIMAP、STARTTLSでSMTP認証を行います。メールアカウントとパスワードはLinuxのシステムを使わずPostfix側で行います。メーラー(MUA)はLMTPプロトコルでDovecotからPostfixに送りインターネットに送信するようにします。

パッケージのインストール

  • postfix(必須)
  • dovecot(必須)
  • postgrey(オプション)
  • opendkim(オプション)
  • fail2ban(オプション)
  • RoundCube – webmail(オプション)
apt install postfix dovecot-core dovecot-imapd dovecot-lmtpd postfix-policyd-spf-python sasl2-bin

SSL Certificate

SSL CertificateはフリーのStartSSLを使いました。まずStartSSLサイトでユーザー登録してサーバー鍵で作ったCSRを使いサイトで登録したホスト名に対してCSRをペーストします。するとzipファイルを作ってくれるのでそれをダウンロードします。zipファイルにはいくつかサーバごとにzipが纏められていますが、OtherServer.zipを展開して、サーバ証明と中間証明を結合します。StartSSLのルート証明書も一緒についてきますが、Ubuntu(16.04 LTS Xenial)等のディストリビューションにはすでにあるのでそれを使います。

Let’s Encryptを使う場合はウェブサーバーが必要になります。 (オススメ)

ファイヤーウォールで次のポートを開けます。

port 25 (SMTP), 587(submission), 143(imap) and 993 (imaps)
optional: 80(http), 443(https)

 

 

メールアカウント

パスワードは平文パスワードを暗号化したHUSHを使います。次のようにして作成します。

sudo doveadm pw -s SHA512-CRYPT -p <平文パスワード>

暗号化したHUSH情報は /etc/dovecot/usersに保存します。

<メールアカウント>:<HUSH>

パスワードのチェックは次のようにします。

sudo doveadm pw -t ’HUSH’

例)doveadm pw -t ’{SHA512-CRYPT}$6$VaEOV5m...'

postmaster_addressがないというエラーがある場合、/etc/dovecot/conf.d/15-lda.confに次のように追加します。

postmaster_address = postmaster@{server名}

ログの解析

エラーがでたらサイトで検索してみるにしても、ログをみて原因を発見し簡単に直ることも多いものです。ターミナルを別に開き、tail -f /var/log/mail.logで常時監視します。さらに、認証でのエラーがメールサーバの時は特に多いので、/etc/dovecot/conf.d/10-logging.confで次のようにしてデバッグします。設定が問題なく完成したらもとに戻します。

auth_debug_passwords = yes

Fail2banのインストール(Optional)

ユーザーの制限にFail2banがいいとのことので入れてみました。Iptablesのlimitとあまり違いがないみたいだけど、メールで知らせてくれたりと機能的には優れています。

設定はとても簡単で/etc/fail2ban/jail.dに設定ファイル追加だけです。Ubuntu Xenialではdefaults-debian.confがインストールされていて、sshがデフォルトで設定してあります。それを参考に例えばメールサーバーの場合、次の内容で設定ファイルを作ります。

[postfix-rbl]
 enabled = true
sudo systemctl restart fail2ban

で再起動すれば新しい設定が有効になります。iptablesで調べるには、

sudo iptables -S
 -P INPUT ACCEPT
 -P FORWARD ACCEPT
 -P OUTPUT ACCEPT
 -N f2b-postfix-rbl
 -N f2b-sshd
 -A INPUT -p tcp -m multiport --dports 25,465,587 -j f2b-postfix-rbl
 -A INPUT -p tcp -m multiport --dports 22 -j f2b-sshd
 -A f2b-postfix-rbl -j RETURN
 -A f2b-sshd -j RETURN

とこのように表示されFail2banが動いているのが分かります。

opendkimのインストール

sudo apt-get install opendkim opendkim-tools

/etc/opendkim.conf

Syslog			yes
UMask			007
Domain                  hottuna.tk
KeyFile                 /etc/dkimkeys/myselector.private
Selector                myselector
Socket                  inet:8891@localhost
UserID                  opendkim
PidFile                 /var/run/opendkim/opendkim.pid
OversignHeaders		From
TrustAnchorFile         /usr/share/dns/root.key

キーを作成します。

cd /etc/dkimkeys 
sudo opendkim-genkey  -s myselector -d <server name>
sudo chown opendkim: *

DNSレコードのtxtを編集します。

myselector._domainkey IN TXT "v=DKIM1; k=rsa; s=email; p=xxxxxxxxxxxxxxxxxxxxxxxxxx"

postfixの設定をします

/etc/postfix/main.cf

milter_default_action = accept
milter_protocol       = 2
smtpd_milters         = inet:localhost:8891
non_smtpd_milters     = inet:localhost:8891

/etc/default/opendkim

SOCKET="inet:8891@localhost"

再起動します

systemctl restart opendkim
systemctl restart postfix

dkimのテストしてみます

host -t TXT myselector._domainkey.hottuna.tk

または

dig myselector._domainkey.hottuna.tk txt

結果

; <<>> DiG 9.11.3-1ubuntu1.8-Ubuntu <<>> myselector._domainkey.hottuna.tk txt
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62394
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;myselector._domainkey.hottuna.tk. IN	TXT

;; ANSWER SECTION:
myselector._domainkey.hottuna.tk. 3600 IN TXT	"v=DKIM1; h=sha256; k=rsa;  p=.....

メールヘッダーのチェックの方法は次のサイトにメールヘッダーをコピーして調べます

1	Authentication-Results	spf=pass (sender IP is xx.xx.xx.xx) smtp.mailfrom=hottuna.tk; hotmail.com; dkim=pass (signature was verified) header.d=hottuna.tk;hotmail.com; dmarc=temperror action=none header.from=hottuna.tk;

 

他DNSレコード編集

逆引きはVPS等の管理者に連絡。

MXA[IP ADDRESS]
MXmx.[DOMAIN NAME]
TXTv=spf1 +a:[DOMAIN NAME]
+a:mx.[DOMAIN NAME] +mx ~a
MYSELECTOR._DOMAINKEYTXTv=DKIM1; h=sha256; k=rsa; s=email; p=M……

設定例

postfix

/etc/postfix/main.cf

compatibility_level = 2 
command_directory = /usr/sbin 
daemon_directory = /usr/lib/postfix/sbin 
data_directory = /var/lib/postfix 
mail_owner = postfix 
myhostname = mx.<server name> 
mydomain = <server name> 
myorigin = $mydomain 
inet_interfaces = all 
mydestination = localhost, mx.$mydomain 
local_recipient_maps = unix:passwd.byname $alias_maps 
unknown_local_recipient_reject_code = 550 
mynetworks = 127.0.0.0/8, 192.168.10.0/24, 192.168.1.0/27, 192.168.250.1/32, 192.168.200.0/24 
virtual_transport = lmtp:unix:private/dovecot-lmtp 
virtual_mailbox_domains = $mydomain 
virtual_alias_maps = hash:/etc/postfix/virtual_aliases 
relay_domains =  
relayhost = 
alias_maps = hash:/etc/aliases 
alias_database = hash:/etc/aliases 
smtpd_banner = $myhostname ESMTP 
debugger_command = 
         PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin 
         ddd $daemon_directory/$process_name $process_id & sleep 5 
sendmail_path = /usr/sbin/postfix 
newaliases_path = /usr/bin/newaliases 
mailq_path = /usr/bin/mailq 
setgid_group = postdrop 
inet_protocols = ipv4 
message_size_limit = 10485760
#smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
#smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_CAfile = /etc/ssl/certs/ca-certificates.crt 
smtpd_tls_cert_file = /etc/ssl/certs/<server name>.crt 
smtpd_tls_key_file = /etc/ssl/private/<server name>.key 
#smtpd_tls_security_level = encrypt
#smtp_tls_security_level = encrypt
smtpd_tls_security_level = may 
smtp_tls_security_level = may 
smtpd_tls_mandatory_ciphers = high
smtpd_tls_mandatory_exclude_ciphers = aNULL, MD5
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
smtpd_sasl_auth_enable = yes 
smtpd_sasl_type = dovecot 
smtpd_sasl_path = private/auth 
smtpd_tls_auth_only = yes 
smtpd_recipient_restrictions = permit_sasl_authenticated, 
        reject_invalid_hostname, 
        reject_unknown_recipient_domain, 
        reject_unauth_destination, 
        reject_rbl_client sbl.spamhaus.org, 
        permit 
smtpd_helo_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
#        check_client_access cidr:/etc/postfix/local.cidr,
        reject_invalid_helo_hostname,
        reject_non_fqdn_helo_hostname,
        reject_unknown_helo_hostname
recipient_delimiter = + 
non_smtpd_milters=inet:127.0.0.1:8891 
smtpd_milters=inet:127.0.0.1:8891 
milter_default_action = accept 
milter_protocol = 2

!SSLv2のエラーがある場合は次のように設定します。

smtpd_tls_mandatory_protocols = TLSv1

 

Optional:

[ここから]

gmail宛のメールをリレーサーバーにする場合:

/etc/postfix/main.cfに追加します。

transport_maps = hash:/etc/postfix/transport
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
mtp_sasl_mechanism_filter = plain, login
smtp_use_tls = yes

/etc/postfix/transport

gmail.com smtp:[smtp.gmail.com]:587

/etc/postfix/sasl_passwd

[smtp.gmail.com]:587 <user name>@gmail.com:<gmail password>
sudo chmod 400 /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/transport

[ここまで]

/etc/postfix/master.cf

smtp      inet  n       -       y       -       -       smtpd 
submission inet n       -       y       -       -       smtpd 
  -o smtpd_sasl_auth_enable=yes 
pickup    unix  n       -       y       60      1       pickup 
cleanup   unix  n       -       y       -       0       cleanup 
qmgr      unix  n       -       n       300     1       qmgr 
tlsmgr    unix  -       -       y       1000?   1       tlsmgr 
rewrite   unix  -       -       y       -       -       trivial-rewrite 
bounce    unix  -       -       y       -       0       bounce 
defer     unix  -       -       y       -       0       bounce 
trace     unix  -       -       y       -       0       bounce 
verify    unix  -       -       y       -       1       verify 
flush     unix  n       -       y       1000?   0       flush 
proxymap  unix  -       -       n       -       -       proxymap 
proxywrite unix -       -       n       -       1       proxymap 
smtp      unix  -       -       y       -       -       smtp 
relay     unix  -       -       y       -       -       smtp 
showq     unix  n       -       y       -       -       showq 
error     unix  -       -       y       -       -       error 
retry     unix  -       -       y       -       -       error 
discard   unix  -       -       y       -       -       discard 
local     unix  -       n       n       -       -       local 
virtual   unix  -       n       n       -       -       virtual 
lmtp      unix  -       -       y       -       -       lmtp 
anvil     unix  -       -       y       -       1       anvil 
scache    unix  -       -       y       -       1       scache 
maildrop  unix  -       n       n       -       -       pipe 
  flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient} 
uucp      unix  -       n       n       -       -       pipe 
  flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) 
ifmail    unix  -       n       n       -       -       pipe 
  flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient) 
bsmtp     unix  -       n       n       -       -       pipe 
  flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient 
scalemail-backend unix  -       n       n       -       2       pipe 
  flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension} 
mailman   unix  -       n       n       -       -       pipe 
  flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py 
  ${nexthop} ${user}

/etc/postfix/reject_sender

touch reject_sender
postmap /etc/postfix/reject_sender

/etc/postfix/virtual_aliases

postmaster          root 
webmaster           root
 # Person who should get root's mail 
root                (user1)
info@<server name>  (user1)
sudo adduser --system --home /var/vmail --uid 550 --group --disabled-login vmail
sudo postmap /etc/postfix/virtual_aliases

dovecot

/etc/dovecot/dovecot.conf

!include_try /usr/share/dovecot/protocols.d/*.protocol 
listen = * 
dict { 
} 
!include conf.d/*.conf 
!include_try local.conf

/etc/dovecot/conf.d/10-auth.conf

disable_plaintext_auth = yes 
auth_mechanisms = plain login
!include auth-system.conf.ext

/etc/dovecot/conf.d/10-logging.conf: (デバッグ用です)

log_path = syslog
auth_debug_passwords = yes  # for debug
plugin { 
}

/etc/dovecot/conf.d/10-mail.conf

mail_location = maildir:/var/vmail/%d/%n 
passdb { 
  driver = passwd-file 
  args = scheme=CRYPT username_format=%u /etc/dovecot/users 
} 
userdb { 
  driver = static 
  args = uid=vmail gid=vmail home=/var/vmail/%d/%n 
} 
namespace inbox { 
  inbox = yes
}

/etc/dovecot/conf.d/10-master.conf

service imap-login { 
  inet_listener imap { 
    port = 0 
  } 
  inet_listener imaps { 
    port = 993 
    ssl = yes
  } 
} 
service pop3-login { 
  inet_listener pop3 { 
  } 
  inet_listener pop3s { 
  } 
} 
service lmtp { 
  unix_listener /var/spool/postfix/private/dovecot-lmtp { 
    mode = 0666 
    user = postfix 
    group = postfix 
  } 
} 
service imap { 
} 
service pop3 { 
} 
service auth { 
  unix_listener /var/spool/postfix/private/auth { 
    mode = 0666 
    user = postfix 
    group = postfix 
  } 
  user = $default_internal_user 
} 
service auth-worker { 
  user = $default_internal_user 
} 
service dict { 
  unix_listener dict { 
  } 
}

/etc/dovecot/conf.d/10-ssl.conf

ssl = required 
ssl_cert = </etc/letsencrypt/live/<mydomain>/fullchain.pem
ssl_key = </etc/letsencrypt/live/<mydomain>/privkey.pem
ssl_protocols = !SSLv3
ssl_cipher_list = kEECDH:+kEECDH+SHA:kEDH:+kEDH+SHA:+kEDH+CAMELLIA:kECDH:+kECDH+SHA:kRSA:+kRSA+SHA:+kRSA+CAMELLIA:!aNULL:!eNULL:!SSLv2:!RC4:!MD5:!DES:!EXP:!SEED:!IDEA:!3DES

/etc/dovecot/conf.d/15-lda.conf

postmaster_address = postmaster@<server name>
protocol lda { 
}

/etc/dovecot/conf.d/20-imap.conf

otocol imap { 
}

/etc/dovecot/conf.d/20-lmtp.conf

protocol lmtp { 
}

/etc/dovecot/conf.d/20-pop3.conf

protocol pop3 { 
}

Optional: ユーザーパスワードの作成

pass-creator.sh

#!/bin/sh

pass=`date +%N | sha256sum | base64 | head -c 16 ; echo`
domain=`postconf -f | grep ^mydomain | sed 's/^mydomain\s*=\s*\(.*\)$/\1/'`
passfile="users"
readable_pass="users-pass.txt"
DOVECOT_CONF="/etc/dovecot"

echo
echo -n "Name: "
read name
echo
mailpass=`doveadm pw -s SHA512-CRYPT -p $pass`
doveadm pw -t $mailpass -p $pass | grep -q \(verified\)

if [ "$?" -eq "0" ]; then
        echo "Password check --> OK"
else
        echo "Password check --> Failed"
        exit 1
fi

echo "${name}@${domain}:${mailpass}" >> $DOVECOT_CONF/$passfile
echo "${name}@${domain} : ${pass}" >> $readable_pass
echo
echo "Account  : ${name}@${domain}"
echo "Password : ${pass}"
echo
exit 0

Postgrey

/etc/postfix/main.cf

smtpd_recipient_restrictions =
  check_policy_service inet:127.0.0.1:10023

/etc/default/postgrey

OSTGREY_OPTS="--inet=10023"

Roundcubeの設定

install

apt install roundcube roundcube-mysql roundcube-plugins php-net-idna2

データベース
MySQL:

CREATE DATABASE roundcubemail /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
GRANT ALL PRIVILEGES ON roundcubemail.* TO 'roundcube'@'<roundcube IP>' IDENTIFIED BY '<password>';
FLUSH PRIVILEGES;

RoundCube:

roundcube HOST:
cd /usr/share/dbconfig-common/data/roundcube/{install | upgrade}
mysql -h <mysql IP> -u roundcube -D roundcubemail -p < mysql

/etc/roundcube/debian-db.php

<?php
$dbuser='roundcube';
$dbpass='<password>';
$basepath='';
$dbname='roundcubemail';
$dbserver='<IP or localhost>';
$dbport='3306';
$dbtype='mysql';

/etc/roundcube/config.inc.php

<?php
$config = array();
include_once("/etc/roundcube/debian-db-roundcube.php");
$config['default_host'] = 'ssl://<host name>';
$config['smtp_server'] = 'tls://<host name>';
$config['smtp_port'] = 587;
$config['smtp_user'] = '%u';
$config['smtp_pass'] = '%p';
$config['support_url'] = '';
$config['product_name'] = 'Roundcube Webmail';
$config['des_key'] = 'x*********************';
$config['plugins'] = array(
'archive',
'zipdownload',
);
$config['skin'] = 'larry';

/etc/roundcube/defaults.inc.php

...

$config['smtp_server'] = '<host name>';
$config['smtp_port'] = 587;
$config['smtp_user'] = '';
$config['smtp_pass'] = '';
$config['smtp_auth_type'] = '';
$config['smtp_auth_cid'] = null;
$config['smtp_auth_pw'] = null;
$config['smtp_helo_host'] = '';
$config['smtp_timeout'] = 0;
$config['smtp_conn_options'] = null;
$config['mime_types'] = '/etc/roundcube/mime.types';
$config['log_dir'] = '/var/log/roundcube/';
$config['temp_dir'] = '/var/cache/roundcube';


...
...

$config['cipher_method'] = 'AES-256-CBC';

...

/etc/hosts(ポートフォワーディングしている場合)

...

<HOST IP> <host name>  # e.g: 192.168.1.1  mymail.com

...

/etc/nginx/sites-enabled/mail

server {
    listen         80;
    server_name    <host name>;

    #location = /50x.html {
    #    root /usr/share/nginx/html;
    #}
    #error_page 404 /404.html;
    #error_page 500 502 503 504 /50x.html;

     location /webmail {
        alias /var/lib/roundcube;
        index index.php
        error_log /var/log/nginx/roundcube.error;
        access_log /var/log/nginx/roundcube.access;
        # Favicon
        location ~ ^/webmail/favicon.ico$ {
            root /var/lib/roundcube/skins/classic/images;
            log_not_found off;
            access_log off;
            expires max;
        }
        # Robots file
        location ~ ^/webmail/robots.txt {
            allow all;
            log_not_found off;
            access_log off;
        }
        # Deny Protected directories 
            location ~ ^/webmail/(config|temp|logs)/ {
            deny all;
        }
        location ~ ^/webmail/(README|INSTALL|LICENSE|CHANGELOG|UPGRADING)$ {
            deny all;
        }
        location ~ ^/webmail/(bin|SQL)/ {
            deny all;
        }
        # Hide .md files
        location ~ ^/webmail/(.+\.md)$ {
                deny all;
        }
        location ~ ^/webmail/\. {
                deny all;
                access_log off;
                log_not_found off;
        }
        #Roundcube fastcgi config
        location ~ /webmail(/.*\.php)$ {
            fastcgi_pass unix:/run/php/php7.2-fpm.sock;
            fastcgi_split_path_info ^/webmail/(.+\.php)(/.*)$;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $request_filename;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param PHP_VALUE open_basedir="/tmp/:/usr/share/roundcube:/var/cache/roundcube:/var/lib/roundcube:/etc/roundcube:/var/lib/roundcube/temp:/var/log/roundcube:/usr/share/php";
            include fastcgi_params;
        }
    }
}

/etc/php/7.2/fpm/php.ini

date.timezone = Asia/Tokyo
systemctl reload php7.2-fpm

インストーラーの設定:(設定後’false’に変えます)

/etc/roundcube/defaults.inc.php

$config['enable_installer'] = true;
cd /usr/share/roundcube
ln -s /etc/roundcube config
cd /var/lib/roundcube
ln -s /usr/share/roundcube/installer/ .
cd /etc/roundcube
chown root:www-data config.inc.php debian-db.php defaults.inc.php 
chmod 640 config.inc.php debian-db.php defaults.inc.php
mkdir -p /var/cache/roundcube
chown www-data: /var/log/roundcube /var/cache/roundcube
chmod 640 /var/log/roundcube /var/cache/roundcube
wget http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
mv mime.types /etc/roundcube

debian系は設定が独自なのでDBチェックエラーは無視します。

メールの送受信のテストが済んだらインストーラーを外します。

$config['enable_installer'] = false;
rm /var/lib/roundcube/installer

 

 

Roundcubeのスキン

有料のスキンは機能豊富で良いのですが無料でシンプルなスキンをインストールしてみます。

https://github.com/EstudioNexos/mabola

追記:multiple domainの設定

非常に困ったことに古いドメインを使わざるを得ない状況なったので調べてみました。

DDNSの設定:

IPアドレス、mxドメインはそのままです。

Let’s encrypt:

サブドメインだけでなく、old_domainと組み合わせてマルチドメイン化ができます。これによって認証が可能になります。

Postfix:

ログや検索で調べた結果、つぎのところを変更します。

mydestination = localhost, $myhostname, mx.$old_domain
virtual_mailbox_domains = $mydomain, $old_domain

これで着信はできるようになりました。

References:

IPsec/IKEv2:スマホを介したサイト間の接続

IPsec接続においてNATが2段のときは認証は通るがサブネットがつながらないためエラーになります。そうした場合、virtual IPを利用した方法になりますが、今度は接続した1台しかつながらなくなります。そこでもう少し掘り下げてSNATを使ってサイトとサイトを繋ぐ方法を考えてみます。

レイアウト図:

192.168.1.190/27--192.168.1.161/27
   Thinkpad      Travel router(OpenWrt)   
                  192.168.43.200/24--192.168.43.1/24
                                        Droid
                                        APN(Pub IP)--61.*.*.*/32
                                                        VPS
                                                     192.168.10.1/24--.10.101-105
                                                                       Server1-5

Travel RouterはスマートフォンのテザリングでVPSとVirtual IPでつながっています。

Travel Router        VPS
192.168.100.1/32 === 192.168.10.0/24

この接続ではTravel RouterからVPSに接続する分にはなんの問題もありません。ところがルーターに繋がれたThinkpadはipsecのルールで192.168.100.1のIPしかトンネルを通過できません。そこでsnatを使うとローカルアドレスを192.168.100.1に書き換えることによってトンネルを通過することができるようなります。

OpenWrtのWEBコントロールパネルでNetwork>Firewall>Traffic Rules>Source NATで設定します。SNAT IP addressは192.168.100.1でよいのですが、Source IP addressがIPの範囲で設定できるかOpenWrtのサイトを覗いたがよくわからなかったので、ネットワークアドレスで指定してみました。具体的には192.168.1.176/28として192.168.1.160/27サブネットを2分割しました。サブネット192.168.1.176/28はsnatでvpsに接続できますが、サブネット192.168.1.160/28はできません。

設定例)

リモートサーバ(GW側)のipsec.conf:

config setup
 plutostart=no
 conn %default
 ikelifetime=60m
 keylife=20m
 rekeymargin=3m
 keyingtries=1

conn common
 keyexchange=ikev2
 leftcert=ServerCert.pem
 leftsourceip=%config 
 leftid=****.vps.*****.jp
 leftauth=pubkey
 leftfirewall=yes

# EAP for travelrouter
conn vps-travelrouter
 left=%defaultroute
 leftsubnet=192.168.10.0/24
 leftsendcert=always
 right=%any
 rightid="C=US, O=MyDomain, CN=wmr300-linux@*****.***dns.jp"
 rightid2=wmr300-ap@*****.***dns.jp
 rightauth=pubkey
 rightallowany=yes
 rightsourceip=192.168.100.1/32
 dpdaction=clear
 dpddelay=300s
 rekey=no
 reauth=no
 fragmentation=yes
 eap_indentity=%any
 ike=aes128-sha256-modp2048,aes256-sha384-modp2048,aes256-sha256-modp2048
 esp=aes128-sha256-modp2048,aes256-sha384-modp2048,aes256-sha256-modp2048
 also=common
 auto=add

Travel router側のipsec.conf:

config setup

conn %default
 ikelifetime=60m
 keylife=20m
 rekeymargin=3m
 keyingtries=1

conn common
 leftcert=ClientCert.pem
 leftsourceip=%config
 leftid2=wmr300-ap@*****.***dns.jp
 leftauth=pubkey
 leftfirewall=yes
 keyexchange=ikev2

conn vps
 left=%any
 right=******.vps.*****.jp
 #rightid=@******.vps.****.jp
 rightsubnet=192.168.10.0/24
 rightauth=pubkey
 also=common
 auto=start

OpenWrt:/etc/config/firewall

config redirect
 option target 'SNAT'
 option src 'lan'
 option dest 'wan'
 option proto 'all'
 option src_dip '192.168.100.1'
 option name 'test'
 option src_ip '192.168.1.176/28'

以上で完成です。

 

Android: SSHデーモンを有効にする(obsolete)

UPDATE: Android: SSHデーモンを有効にする

Android:でsshサーバーを有効にするには次にようにします。

adbを使えるようにする

まずアンドロイド機をrootで使えるようにデベロッパーモードにします。つぎにLinux機にパッケージをインストールします。

sudo apt-get install android-tools-adb
sudo apt-get install android-tools-fastboot

スマホをusb接続してadb shellでアクセスする。pubキーをコピーするときに

adb push your_public_key /data/.ssh/authorized_keys

コピーでパミッションエラー等でうまくいかない場合次のようにします。

cat >/data/.ssh/authorized_keys<<EOF
(PCのpubキーをコピペ)
EOF

/data/localuserinit.shを作成し次のように編集しchmod +xで実行モードにする。

#!/bin/sh

for i in $(echo /data/local/userinit.d/*) 
do $i & 
done

次に、/data/sshに移動して、

ln -s ../.ssh/authorized_keys

とリンクを張ります。

これで、/system/etc/init.d/90userinitを実行してsshが動いているかpsコマンド確認して動いていればOK.

あとはWi-Fiテザリングで接続してみます。route -nでデフォルトGWが表示されるのでそのアドレスにアクセスします。

$ ssh shell@192.168.43.1

以上で完了です。

Fonera 2100: Attitude Adjustment 12.09にアップデート

 

OppenWrtのファームウェアのアップデートです。ファイルサイズが変わるので fis freeでメモリのサイズを把握して適切な数値をいれてインストールします。

 RedBoot> ip_address -l 192.168.1.254/24 -h 192.168.1.2
 IP: 192.168.1.254/255.255.255.0, Gateway: 0.0.0.0
 Default server: 192.168.1.2
 RedBoot> load -r -b %{FREEMEMLO} openwrt-atheros-vmlinux.lzma
 Using default protocol (TFTP)
 Raw file loaded 0x80040800-0x801207ff, assumed entry at 0x80040800
 RedBoot> fis init
 About to initialize [format] FLASH image system - continue (y/n)? y
 *** Initialize FLASH Image System
 ... Erase from 0xa87e0000-0xa87f0000: .
 ... Program from 0x80ff0000-0x81000000 at 0xa87e0000: .
 RedBoot> fis create -e 0x80041000 -r 0x80041000 vmlinux.bin.l7
 ... Erase from 0xa8030000-0xa8110000: ..............
 ... Program from 0x80040800-0x80120800 at 0xa8030000: ..............
 ... Erase from 0xa87e0000-0xa87f0000: .
 ... Program from 0x80ff0000-0x81000000 at 0xa87e0000: .
 RedBoot> fis free
 0xA8110000 .. 0xA87E0000
 RedBoot> load -r -b %{FREEMEMLO} openwrt-atheros-root.jffs2-64k
 Using default protocol (TFTP)
 Raw file loaded 0x80040800-0x803207ff, assumed entry at 0x80040800
 RedBoot> fis create -l 0x6D0000 rootfs
 RedBoot> fconfig boot_script_data
 >> fis load -l vmlinux.bin.l7
 >> exec
 >>
 RedBoot> reset

再度インストールし直すのであればmtdを使うことも可能です。

root@OpenWrt:/tmp# mtd -e vmlinux.bin.l7 write openwrt-atheros-vmlinux.lzma vmlinux.bin.l7
root@OpenWrt:/tmp# mtd -e rootfs write openwrt-atheros-root.jffs2-64k rootfs

 

 

 

インストールが正しく出来てもブートできないケースが結構ありました。

 [ 27.600000] jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x000e0024: 0xd65a instead
 [ 27.710000] Further such events for this erase block will not be printed
 [ 28.320000] Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes
 [ 28.420000] empty_blocks 93, bad_blocks 0, c->nr_blocks 108
 [ 28.480000] VFS: Cannot open root device "(null)" or unknown-block(31,2)
 [ 28.560000] Please append a correct "root=" boot option; here are the available partitions:
 [ 28.660000] 1f00 192 mtdblock0 (driver?)
 [ 28.720000] 1f01 960 mtdblock1 (driver?)
 [ 28.790000] 1f02 6912 mtdblock2 (driver?)
 [ 28.850000] 1f03 60 mtdblock3 (driver?)
 [ 28.910000] 1f04 4 mtdblock4 (driver?)
 [ 28.970000] 1f05 64 mtdblock5 (driver?)
 [ 29.030000] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,2)

この場合、1,2度再インストールすればOK。原因は不明です。

問題点

メモリに厳しい制約がありちょっと大きいパッケージをインストールしようとすると

root@OpenWrt:~# opkg install wpa-supplicant_20131120-1_atheros.ipk
 Collected errors:
 * gz_open: fork: Cannot allocate memory.
 * pkg_init_from_file: Failed to extract control file from wpa-supplicant_20131120-1_atheros.ipk.

のようにエラーでインストールできません。
この場合はhttpでサイトのパッケージを指定してopkgでインストールできます。

IPsec関係のトラブルシュート

connの使い分けに失敗するとき

FQDNを証明書の作成およびipsec.confで一致してるか確認します。leftidをつぎのように証明書の作成と一致させるか

leftid="C=JP, O=MyDomain, CN..."

またはleftid2で’–san’を指定します。

leftid2=router@xxxxxx.xxxxdns.jp

CAの内容を調べてチェックします。

ipsec pki --print --in /etc/ipsec.d/certs/xxxxCert.pem
openssl x509 -in /etc/ipsec.d/certs/xxxxCert.pem -text -noout
ipsec listcerts

sshフリーズの問題

sshでログインできるがフリーズする問題はmtuの問題です。値を1492に、それでもつながらない時は数値を下げて調整します。

CA証明書、サーバー鍵はVPSでは作らない

VPSはエントロピーが溜まりにくいのでランダムな暗号の作成ができません。エントロピーの確認は、

$ cat /proc/sys/kernel/random/entropy_avail

4000程度あれば大丈夫です。

 

OpenWrtはipsecのtranportモードをサポートしない

OpenWrtはtransportモードをサポートしません。L2TP/ipsecはtransportモードで作動しtunnelモードでは作動しないのでOpenWrtを使うとすれば、tunnelでIKEv2を使う選択がよいと思われます。

IPsec: strongSwanのClient側のOpenWrtの設定(Site to Site)

パッケージをインストールします。

opkg update
opkg install strongswan-full strongswan-utils kmod-cypto-sha256
opkg remove ip
opkg install ip-full

Client鍵と証明書とCA証明書をインストールします。(証明書の作成方法 : IPsecによるVPNのセキュアな接続)

cp clientCert.pem /etc/ipsec.d/certs
cp clientKey.pem /etc/ipsec.d/private
cp caCert.pem /etc/ipsec.d/cacerts

strongSwanの設定例です。

/etc/ipsec.conf:

config setup

conn %default
 ikelifetime=60m
 keylife=20m
 rekeymargin=3m
 keyingtries=1
 keyexchange=ikev2

conn common
 left=%any
 leftcert=serverCert.pem
 leftid="C=JP, O=MyDomain, CN=router@xxxx.xxxdns.jp --san=router@xxxx.xxxdns.jp"
 leftid2=router@xxxx.xxxdns.jp
 leftauth=pubkey
 leftfirewall=yes
 leftsourceip=%config
 leftsubnet=192.168.10.0/24
 right=xxxxxx.vps.xxxxxx.jp
 rightid=@xxxxxx.vps.xxxxxx.jp
 rightauth=pubkey
 rightfirewall=yes
 ike=aes128-sha256-modp2048
 esp=aes128-sha256-modp2048
 auto=start

/etc/ipsec.secrets:

: RSA clientKey.pem

/etc/strongswan.conf:

charon {

load_modular = yes
   dns1 = 8.8.8.8
   dns2 = 8.8.4.4
 threads = 16
  plugins {
 include strongswan.d/charon/*.conf
 }
}

/etc/strongswan.d/charon/kernel-netlink.conf:

mtu = 1376

fwの設定

espプロトコル、500、4500ポートを通すようにします。次の例のように追加します。

/etc/config/firewall:

config rule 
        option src 'wan' 
        option proto 'esp' 
        option target 'ACCEPT' 
 
config rule 
        option src 'wan' 
        option proto 'udp' 
        option dest_port '500' 
        option target 'ACCEPT' 
 
config rule 
        option src 'wan' 
        option proto 'udp' 
        option dest_port '4500' 
        option target 'ACCEPT'

/etc/firewall.user

iptables -I INPUT -m policy --dir in --pol ipsec --proto esp -j ACCEPT 
iptables -I FORWARD -m policy --dir in --pol ipsec --proto esp -j ACCEPT
iptables -I FORWARD -m policy --dir out --pol ipsec --proto esp -j ACCEPT
iptables -I OUTPUT -m policy --dir out --pol ipsec --proto esp -j ACCEPT
iptables -t nat -I POSTROUTING -m policy --pol ipsec --dir out -j ACCEPT

追記:

IPsecのrouting方法

この1行を/etc/firewall.userに追加するとルーティングが可能になります。

iptables -t nat -I POSTROUTING -m policy --pol ipsec --dir out -j ACCEPT

 

IPsec関係のコマンド集

ipsec(strongSwan)とipの基本のコマンド

journalctl -u strongswan -f: DebianなどでSystemdを使っている場合のログ表示

ipsec start –nofork: ipsecを起動してログをフロントエンドに表示(テスト用)

ipsec statusall: 起動状況、接続状況を表示

ipsec stroke up/down {conn name}: conn名の設定を起動/停止

ip route show table 220: ipsecのルーティング表示

ip xfrm state: トンネル状況を表示

ip xfrm policy: トンネル状況を表示

 

IPsecによるVPNのセキュアな接続(サーバー編)

はじめに

VPNの接続にはOpenVPNやL2TPなどいろいろな方法がありますが、なかでもIPsecを使った接続はよりセキュアなだけではなく設定に柔軟性があるので、いったん設定できれば応用が利きます。サーバのレンタルVPSとの接続に自宅からだけでなく、外出先からWi-Fiを使った接続、さらにスマートフォンからの接続とあらゆる機器から接続を考えたらIPsecは最もよい選択になります。IPsecには大きく分けてIKEv1とIKEv2あり、ここではよりセキュアなIKEv2を使って設定を進めていきます。VPSのOSはDebian stretch(Debian 9)を使っています。Debian jessieでも設定は同じです。IPsecのアプリケーションはstrongSwanを使用しています。

サーバにaptでパッケージをインストールします。

sudo apt install strongswan strongswan-charon strongswan-ikev2 \
           libstrongswan-extra-plugins libstrongswan-standard-plugins libcharon-extra-plugins

サーバのCA証明書及びServer証明書の作成します。

作成する場所は自分のPCとして進めていきます。

mkdir ~/ipsec
cd ~/ipsec

CA証明書の作成は次のようにスクリプトを作成します。

#!/bin/sh 
 
mkdir -p private cacerts 
openssl genrsa -out private/caKey.pem 4096 
chmod 600 private/caKey.pem 
ipsec pki --self --ca --lifetime 3650 \ 
 --in private/caKey.pem --type rsa \ 
 --dn "C=JP, O=MyDomain, CN=My Root CA" \ 
 --digest sha256 \ 
 --outform pem \ 
 > cacerts/caCert.pem

Server鍵および証明書の作成は次のようにスクリプトを作成します。–san xxxxx… とFQDNにしておきます。

#!/bin/sh 
 
mkdir -p private certs 
 
openssl genrsa -out private/ServerKey.pem 2048 
chmod 600 private/ServerKey.pem 
ipsec pki --pub --in private/ServerKey.pem --type rsa  | \ 
 ipsec pki --issue --lifetime 1095 \ 
 --cacert cacerts/caCert.pem \ 
 --cakey private/caKey.pem \ 
 --dn "C=JP, O=MyDomain, CN=xxxxxxxxx.vps.xxxxxx.jp" \ 
 --san xxxxxxxxx.vps.xxxxxx.jp \ 
 --digest sha256 \ 
 --flag serverAuth --flag ikeIntermediate \ 
 --outform pem > certs/ServerCert.pem

Client鍵および証明書の作成は次のようにスクリプトを作成します。クライアントの方も同様に’–san’をFQDNに設定します。またconnによって使い分けするので’–dn’の’CN=’をname@FQDN名とします。

注)ipsecよりopensslのほうが精度よい鍵が作れます

#!/bin/sh 
 
#id=1
NAME=MyLinux
 
CLIENTKEY="ClientKey.pem" 
CLIENTCERT="ClientCert.pem" 
CLIENTCN="${NAME}@xxxx.xxxddns.jp" 
 
#ipsec pki --gen --type rsa --size 2048 --outform pem > $CLIENTKEY 
 
openssl genrsa -out $CLIENTKEY 2048 
 
ipsec pki --pub --in $CLIENTKEY --type rsa | \ 
 ipsec pki --issue --lifetime 1095 \ 
 --cacert cacerts/caCert.pem \ 
 --cakey private/caKey.pem \ 
 --dn "C=JP, O=MyDomain, CN=${CLIENTCN}" \ 
 --san ${CLIENTCN} \ 
 --digest sha256 \ 
 --outform pem > $CLIENTCERT 
 
openssl pkcs12 -export -inkey $CLIENTKEY \ 
 -in $CLIENTCERT -name "My VPN Certificate" \ 
 -certfile cacerts/caCert.pem \ 
 -caname "My Root CA" \ 
 -out ${CLIENTCERT%.pem}.p12

リボーケーションリストの作成は次のようにスクリプトを作成します。

#!/bin/sh 
 
user=<Client証明書>.pem

ipsec pki --signcrl --cacert cacerts/caCert.pem \ 
 --cakey private/caKey.pem \ 
 --reason superseded \ 
 --cert $user \ 
 --outform pem \ 
 > crl.pem

これらのスクリプトのパーミッションと所有者を変更します。

sudo chown root:root *.sh
sudo chmod 755 *sh
sudo ./mk-ca.sh
sudo ./mk-server-key.sh
sudo chown root:root cacerts/* certs/* private/*
sudo chmod 600 /etc/ipsec.d/private/*

証明書を作成したらCAの内容を調べます。方法は次の2通りあります。

1) ipsec pki --print --in /etc/ipsec.d/certs/xxxxCert.pem
2) openssl x509 -in /etc/ipsec.d/certs/xxxxCert.pem -text -noout

scp等でサーバにコピーしてサーバーの設定ファイルにインストールします。

sudo rm /etc/ipsec.d/cacerts/* /etc/ipsec.d/certs/* /etc/ipsec.d/private/*
sudo cp -a cacerts certs private /etc/ipsec.d

IPsecの設定

次の設定は各々のデバイスに対応した設定例です。

/etc/ipsec.conf:

config setup 
 plutostart=no

conn %default 
 ikelifetime=60m 
 keylife=20m 
 rekeymargin=3m 
 keyingtries=1 
 keyexchange=ikev2

conn common 
 # left=%any 
 leftcert=ServerCert.pem 
 leftsourceip=%config 
 leftid=xxxxxxxxxx.vps.xxxxxx.jp 
 leftauth=pubkey 
 leftfirewall=yes

# Site to Site: Router and VPS 
conn home-router 
 left=xxxxxxxxxxx.vps.xxxxxx.jp 
 leftsubnet=xx.xx.xx.254/32 
 right=xxxxxx.xxxddns.jp 
 rightid="C=JP, O=MyDomain, CN=xxxxx@xxxxxx.xxxdns.jp --san=xxxxx@xxxxxx.xxxdns.jp" 
 rightid2=xxxxx@xxxxxx.xxxdns.jp 
 rightsubnet=192.168.1.0/27 
 rightauth=pubkey 
 #rightallowany=yes 
 ike=aes128-sha256-modp2048 
 esp=aes128-sha256-modp2048 
 also=common  
 #auto=route 
 auto=add

# IKEv2 Certificate for Linux and Android
conn vpn-client-linux-android 
 left=%defaultroute 
 leftsubnet=0.0.0.0/0
 right=%any
 rightid2=*linux@xxxxxx.xxxdns.jp
 rightauth=pubkey 
 rightallowany=yes
 rightsourceip=192.168.200.0/24
 dpdaction=clear
 dpddelay=300s
 rekey=no
 reauth=no
 fragmentation=yes
 eap_indentity=%any
 ike=aes256-sha384-modp2048,aes256-sha256-modp2048
 esp=aes256-sha384-modp2048,aes256-sha256-modp2048
 also=common
 auto=add

# EAP-MSCHAPv2 for Windows and macOS 
conn vpn-client-windows-macos 
 left=%defaultroute 
 leftsubnet=0.0.0.0/0 
 leftsendcert=always 
 right=%any 
 rightid2=*@xxxxxx.xxxdns.jp 
 rightsourceip=192.168.200.0/24 
 rightauth=eap-mschapv2 
 ike=aes256-sha1-modp1024,aes128-sha1-modp1024,3des-sha1-modp1024! 
 esp=aes256-sha256,aes256-sha1,3des-sha1! 
 dpdaction=clear 
 dpddelay=300s 
 rekey=no 
 reauth=no 
 fragmentation=yes 
 eap_indentity=%any 
 rightdns=8.8.8.8 
 also=common 
 auto=add

秘密鍵はLinuxではRSAのみ、WindowsとmacOSではRSA+EAPになります。

/etc/ipsec.secrets:

: RSA serverKey.pem 
user : EAP "pass"

include /var/lib/strongswan/ipsec.secrets.inc

Note:ユーザー、パスワードは環境にあわせて変更します。

/etc/strongswan.conf:

charon { 
    load_modular = yes 
    plugins { 
      include strongswan.d/charon/*.conf 
   } 
    dns1 = 8.8.8.8
    dns2 = 8.8.4.4
    threads = 16 
}

libstrongswan { 
    crypto_test { 
    on_add = yes 
    } 
}
include strongswan.d/*.conf

ipsecの属性をIPヘッダに追加するとmtu値が大きくなるため変更します。

/etc/strongswan.d/charon/kernel-netlink.conf:

mtu = 1352

Shorewall(firewall)の設定

ファイヤーウォールの設定はEAPプロトコルを通すことと500と4500ポートを開けることです。Shorewallをつかう場合の設定です。

interfaces:
eth0しかないので変更しません。

hosts:
manの説明によると一つインターフェースしかないときzoneで設定するために定義するファイルなので次のようにしました。

#ZONE       HOST(S) OPTIONS 
vpn eth0:0.0.0.0/0

zone:
これはShorewallには必須なので登録します。そのままドキュメントからコピーします。

#ZONE TYPE OPTIONS IN OUT 
# OPTIONS OPTIONS
vpn ipsec mode=tunnel

policy:
ファイヤウォールからvpnにアクセスできるようにする設定です。

#SOURCE DEST POLICY LOG LEVEL LIMIT:BURST
$FW vpn ACCEPT

rules:
ipsecのポートを開けます。

#ACTION SOURCE DEST PROTO DEST SOURCE 
#ACCEPT net $FW ah 
ACCEPT net $FW esp 
ACCEPT net $FW udp 500 
ACCEPT net $FW udp 4500

tunnels:
zoneと対応しておく必要があるので設定します。

#TYPE ZONE GATEWAY(S) GATEWAY 
ipsec net 0.0.0.0/0 vpn

start:

Shorewallのシステムで対応できない設定はstartで設定します。

iptables -I INPUT -m policy --dir in --pol ipsec --proto esp -j ACCEPT 
iptables -I FORWARD -m policy --dir in --pol ipsec --proto esp -j ACCEPT 
iptables -I FORWARD -m policy --dir out --pol ipsec --proto esp -j ACCEPT 
iptables -I OUTPUT -m policy --dir out --pol ipsec --proto esp -j ACCEPT
iptables -t nat -I POSTROUTING -m policy --pol ipsec --dir out -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.200.0/24 -o eth0 -m policy --dir out --pol ipsec -j ACCEPT 
iptables -t nat -A POSTROUTING -s 192.168.200.0/24 -o eth0 -j MASQUERADE

以上で、サーバ側の設定は完了です。

References: