iptablesの設定

やること

strongSwanの設定をしただけでは、通信できない。 iptables を設定して、10.1.2.0/24をNATする設定と、IPSecでトンネルしたことでMTUが減るため、 TCPMSSの設定をする。

カーネルの設定

パケットを他のホストに転送するようにする。

$ echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf

MTUはiptablesで設定するため、Path MTU Discoveryは無効にする。

$ echo 'net.ipv4.ip_no_pmtu_disc=1' >> /etc/sysctl.conf

iptablesの設定

コマンドで流し込むだけ。

$ iptables -t mangle -A FORWARD -p tcp -m policy --dir in --pol ipsec -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
$ iptables -t mangle -A FORWARD -p tcp -m policy --dir out --pol ipsec -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360

$ iptables -t nat -A POSTROUTING -s 10.1.2.0/24 -o eth0 -m policy -dir out --pol ipsec -j ACCEPT
$ iptables -t nat -A POSTROUTING -s 10.1.2.0/24 -o eth0 -j MASQUERADE

捕捉

VPNサーバー自体にFIrewallの設定があるなら、UDP Port 500と4500を許可する。

iptables -A INPUT -p udp --dport 4500 -j ACCEPT
iptables -A INPUT -p udp --dport 500 -j ACCEPT

この辺りについては、strongSwanのwikiに記載がある。

Introduction to strongSwan: Forwarding and Split-Tunneling - strongSwan

strongSwanの設定

strongSwanのインストール

普通にaptなどでインストールする。

$ apt install strongswan

証明書の配置

作成しておいた証明書を配置する。

rixwwd.hatenablog.jp

$ cd vpnca
$ sudo cp ca.crt /etc/ipsec.d/cacerts
$ sudo cp server.key /etc/ipsec.d/private
$ sudo cp server.crt /etc/ipsec.d/

設定ファイルの編集

/etc/ipsec.secret

以下の内容を追記する。

 : RSA "/etc/ipsec.d/private/server.key"

/etc/ipsec.conf

以下の内容に書き換える。

config setup
  uniqueids=no
conn tls
  auto=add
  compress=no
  type=tunnel
  keyexchange=ikev2
  forceencaps=yes
  ike=aes256-sha256-modp2048
  esp=aes256-sha256
  dpdaction=clear
  rekey=no
  left=%any
  # サーバ証明書のCNかSANに合わせて設定する。
  leftid=@vpn.example.com
  leftcert=/etc/ipsec.d/certs/server.crt
  leftsendcert=always
  leftsubnet=0.0.0.0/0
  right=%any
  rightid=%any
  # 認証方式 
  rightauth=eap-tls
  # VPNクライアントに割り当てるIPアドレス
  rightsourceip=10.1.2.0/24
  # VPNクライアントに通知するDNSサーバ
  rightdns=8.8.8.8,8.8.4.4
  rightsendcert=always
  eap_identity=%identity

/etc/strongswan.d/charon-logging.conf

接続できなかったときに、調査できるように設定しておく。 最低限以下の設定はないとtail -fで不便。

default = 2
flush_line = yes
time_format = %F %T

macから接続確認

自分のクライアント証明書のインストールは、pkcs12を開けばOK。 VPN Root CAはクライアント証明書のインストールの前にインストールしておき、常に信頼するように設定する。

iPhoneの設定も同じような感じです。

VPN用ダイナミックDNSの登録

やること

VPNの証明書を作るにあたって、ドメイン名をSANに埋め込みたいけどドメイン持ってないのでダイナミックDNSのサービスを使う。 ダイナミックDNSにはno-ipを使った。 定期的にIPドレスを登録し直すことで、IPアドレスが変わった場合に備える。

ダイナミックDNS

no-ipでユーザ登録するだけ。 メールアドレスがあればOK。

定期的な実行

以下のcurlをcron登録して終わり。

# BASIC認証用の値を作成。
$ echo -n 'username:password' | base64

# 定期的に実行するコマンド
$ curl -H 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=' https://dynupdate.no-ip.com/nic/update?hostname=mydomain.example.com

VPN用証明書の作成

やること

iPhoneからVPN接続できるよう、IKEv2なVPN構築する。VPN構築にあたって必要な証明書を作成する。 IKEv2はstrongSwanを使う予定。

CA作成

まずはディレクトリを作る。

$ touch index.txt
$ echo 00 > serial
$ mkdir private newcerts
$ chmod 700 private
$ cat << 'EOF' > openssl.conf
[ ca ]
default_ca      = CA_default

[ CA_default ]

dir            = ./
database       = $dir/index.txt
new_certs_dir  = $dir/newcerts

certificate    = $dir/ca.crt
serial         = $dir/serial
private_key    = $dir/private/ca.key
RANDFILE       = $dir/.rand

default_days   = 365
default_crl_days= 365
default_md     = sha256

policy         = policy_any
email_in_dn    = no

name_opt       = ca_default
copy_extensions = none

[ policy_any ]
countryName            = match
stateOrProvinceName    = optional
organizationName       = optional
organizationalUnitName = optional
commonName             = supplied
emailAddress           = optional
EOF

CA自体の自己署名の証明書を作る。

$ cat << 'EOF' > ca.conf
basicConstraints = CA:true, pathlen:0
keyUsage = digitalSignature,keyCertSign,cRLSign
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
EOF

$ openssl req -new -newkey rsa:2048 -keyout private/ca.key -nodes -out ca.csr -subj '/C=JP/CN=VPN Root CA/'
$ openssl x509 -req -in ca.csr -signkey private/ca.key -out ca.crt -extfile ca.conf -days 3650 -sha256

サーバー証明書

iPhoneからも接続できるように、EKUに1.3.6.1.5.5.8.2.2を追加しておく。subjectAltNameも忘れずに。

$ openssl req -new -newkey rsa:2048 -nodes -keyout server-strongswan.key -out server-strongswan.csr -subj '/C=JP/O=strongSwan/CN=vpn.example.com/'

$ cat << 'EOF' > server.conf
keyUsage = digitalSignature
extendedKeyUsage = serverAuth,1.3.6.1.5.5.8.2.2
subjectAltName = DNS:vpn.example.com
authorityKeyIdentifier=keyid
EOF

$ openssl ca -config openssl.conf -in server-strongswan.csr -out server-strongswan.crt -extfile server.conf

クライアント証明書

VPNの認証はeap-tlsを使いたいため、クライアント証明書も発行する。 CNと同じ値をsubjectAltNameに追加。この値は、VPNの設定するときにローカルIDに入れる。 PKCS12形式の証明書ができるため、CAの証明書と一緒にiPhoneにメールなどで送る。

$ openssl req -new -newkey rsa:2048 -nodes -keyout client-username.key -out client-username.csr -subj '/C=JP/CN=username@vpnusers/'
$ cat << 'EOF' > client.conf
keyUsage = digitalSignature
extendedKeyUsage = clientAuth
subjectAltName = email:username@vpnusers
authorityKeyIdentifier=keyid
EOF
$ openssl ca -config openssl.conf -in client-username.csr -out client-username.crt -extfile client.conf
$ openssl pkcs12 -export -in client-username.crt -inkey client-username.key -out client-username.p12

tf-idf

Wikipediaの解説によると以下で求められるらしい。

tf-idf = tf * idf
tf = ドキュメントのある単語の出現回数 / ドキュメント中の全ての単語の出現回数
idf = log(すべてのドキュメント数 / 単語を含むドキュメント数)

tf-idf

コードを書いて動かして見たらこうなった。

屋根   0.06931471805599453
男性  0.03960841031771116
雪 0.03465735902799726
館 0.02970630773828337
市 0.02970630773828337
----
学校  0.05401146861506067
県 0.036007645743373784
神奈川   0.036007645743373784
支給  0.036007645743373784
朝鮮  0.027005734307530335
----
機関  0.04780325383172036
アメリカ    0.04780325383172036
政府  0.04780325383172036
閉鎖  0.03824260306537629
サービス    0.03824260306537629
----
関東  0.050966704452937155
気圧  0.04077336356234972
雪 0.030580022671762293
月曜日   0.030580022671762293
気象庁   0.030580022671762293
----

とりあえずブログを始めたもののどうしましょう

毎日ブログを書いてアウトプットを増やすことで、強制的に何かインプットするようにと企んでいたど、3日目にしてブログのネタがない。

ブログの記事としては、主に以下の書き方がありそう。

  • 何か作りながら、その開発日記的に書いていく。
  • 日常生活の中で考えたことを書いてく

 

Rubyで形態素解析

まずは、MeCabのインストールから。

$ brew install mecab mecab-ipadic

次にgemのインストール。

$ gem install mecab

で、使う。

require 'mecab'

sentence = "急速に発達する低気圧や暖かく湿った空気の影響で、西日本や東日本を中心に大気の状態が非常に不安定となる見込み。"

model = MeCab::Model.new
tagger = model.createTagger
node = tagger.parseToNode(sentence)

while node do
    puts "#{node.surface}\t#{node.feature}"
    node = node.next
end

ところで、irbでいろいろ試していたけど、日本語の入力がうまくできなかた。 brewでreadlineを入れる前にrbenvを入れていたため、readlineが使われていなかったみたい。 readlineが入っているのを確認して、再インストールしたら解決。

$ brew list | grep readline
$ rbenv uninstall 2.5.0
$ rbenv install 2.5.0