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
証明書の配置
作成しておいた証明書を配置する。
$ 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から接続確認
- サーバアドレス:vpn.example.com(接続するIPアドレスでもOK)
- リモートID:vpn.example.com(サーバー証明書のCN)
- ローカルID:username@vpnusers(クライアント証明書のCN)
- 認証設定:証明書
- 証明書:自分のクライアント証明書
自分のクライアント証明書のインストールは、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(すべてのドキュメント数 / 単語を含むドキュメント数)
コードを書いて動かして見たらこうなった。
屋根 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