Python: Flask: HTTP GET メソッドのクエリパラメータに真偽値を使いたい

うまい例をでっち上げられないので、実際のユースケースで説明する。

自宅のサーバで Flask を使った書籍管理の web アプリを運用してるんだけど(ソースコードは GitHub で公開してある)、その web アプリには JSON を返す API が定義してある。で、API のひとつ /api/books/ は書籍情報の一覧を返し、クエリパラメータとして offset と limit を取ることができる。

Flask では request.args.get でクエリパラメータの値を取得するついでに、値の型とデフォルト値を指定することができる。↓こんな感じ。

@app.route('/api/books/')
def api_books():
    offset = request.args.get('offset', default=0, type=int)
    limit = request.args.get('limit', default=100, type=int)
    ....

さて、この書籍管理アプリには「書籍を削除する」という機能がなくて、かわりに書籍を捨てた時には、データベース上の disposed カラムに True をセットして、web アプリ上では表示しないようになっている。だけど上記の API ではそこのところを考慮してなかったので、返ってくる JSON には捨てた書籍も含まれている、という状況だった。

ここからが本題。

API の返す JSON に、デフォルトでは捨てた書籍(つまり disposed=True)は含まず、クエリで include_disposed に真値をセットした時にだけ含むようにしたい。

最初の方法

上に示したコートでは、クエリパラメータの値を int に変換して取得しているんだから、同様に bool を指定してやればいいと思った。こういうふうに。

@app.route('/api/books/')
def api_books():
    offset = request.args.get('offset', default=0, type=int)
    limit = request.args.get('limit', default=100, type=int)
    include_disposed = request.args.get('include_disposed', default=False, type=bool)
    ....

開発用のサーバはエラーもなく立ち上がり、/aip/books/ にアクセスすると捨てた書籍が含まれていない JSON が、/api/books/?include_disposed=True にアクセスすると捨てた書籍も含まれた JSON が返ってきた。期待通りだ。

ところが、試しに /api/books/?include_disposed=False にアクセスしてみると、捨てた書籍も含まれた JSON が返ってきた。これは期待する動作と違う。

原因は追求していないけど、想像するに、クエリの値として渡っててきた文字列を bool(文字列) してるだけなんじゃなかろうか。だとすると、クエリで include_disposed の値がなんであるかにかかわらず、空文字列でない限りは、変数 include_disposed の値は True になるわけだ。

なんてこった。期待させやがって!

解決編

しかたがないので文字列を真偽値に変換する関数を書いた。一般に真を表すであろう文字列(true、 yes、 on、大文字小文字を問わない)の時だけ True を返し、ほかは False を返す。

def str_to_bool(s):
    p = re.compile(r'(true|yes|on)\Z', re.IGNORECASE)
    if p.match(s):
        return True
    else:
        return False

で、クエリの値を変数に代入するところはこうした。

    include_disposed = str_to_bool(request.args.get('include_disposed', default=''))

request.args.get の返す値を str_to_bool で変換している。default=” を指定しているのは、指定しないとクエリに include_disposed がなかった時に None が返ってくるため。

さて、これで期待通りの動作をするようになった。

カテゴリー: Python | コメントする

CentOS 8: NginxでCGIを利用できるようにする

以前 Ubuntu ではやったけど、今度は CentOS で。

fcgiwrap のインストール

標準のリポジトリには無いようなので EPEL からインストール。

[[email protected] ~]$ sudo dnf -y install epel-release
[[email protected] ~]$ sudo dnf --enablerep=epel -y install fcgiwrap

Nginx の設定

CGI を利用したいサイトの設定ファイルの server セクションにつぎを追加。

location ~ \.cgi$ {
        root  /var/www/app;
        fastcgi_pass  unix:/var/run/fcgiwrap.socket;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        include  /etc/nginx/fastcgi_params;
}

で、Nginx をリスタート。

[[email protected] ~]$ sudo systemctl restart nginx

fcgiwrap 用の設定ファイルを作成して起動。

/usr/lib/systemd/system/fcgiwrap.service

[Unit]
Description=Simple CGI Server
After=nss-user-lookup.target
Requires=fcgiwrap.socket

[Service]
EnvironmentFile=/etc/sysconfig/fcgiwrap
ExecStart=/usr/sbin/fcgiwrap ${DAEMON_OPTS} -c ${DAEMON_PROCS}
User=ngix
Group=root

[Install]
Also=fcgiwrap.socket

/usr/lib/systemd/system/fcgiwrap.socket

[Unit]
Description=fcgiwrap socket

[Socket]
ListenStream=/run/fcgiwrap.socket

[Install]
WantedBy=sockets.target

起動。

[[email protected] system]$ sudo systemctl enable --now fcgiwrap

SELinux

SELinux を有効にしているので、ポリシーを作る。

nginx-server.te

module nginx-server 1.0;

require {
    type httpd_t;
    type var_run_t;
    class sock_file write;
}

#======== httpd_t ========
allow httpd_t var_run_t:sock_file write;
[[email protected] ~]$ sudo checkmodule -m -M -o nginx-server.mod nginx-server.te
[[email protected] ~]$ sudo semodule_package --outfile nginx-server.pp --module nginx-server.mod
[[email protected] ~]$ sudo semodule -i nginx-server.pp

CGI のテスト

設定したディレクトリ(今回は /var/www/app)の中に、hello.cgi を作成。

#!/usr/bin/env ruby

print "Content-type: text/html\n\n"
print <<EOC
<html>
  <body>
    <h1>Hello</h1>
    <p>Hello, from CGI!</p>
  </body>
</html>
EOC

実行権限をつけるのを忘れずに。

今回はスマホから確認した。OKだった。

カテゴリー: CentOS, Misc | コメントする

UbuntuでOneDriveをつかう

下準備

必要なパッケージをインストールする。

[email protected] $ sudo apt install libcurl4-openssl-dev libsqlite3-dev gdebi
[email protected] $ wget http://downloads.dlang.org/releases/2020/dmd_2.090.1-0_amd64.deb
[email protected] $ sudo gdebi dmd_2.090.1-0_amd64.deb

OneDrive Client のインストール

[email protected] $ git clone [email protected]:skilion/onedrive.git
[email protected] $ cd onedrive
[email protected] $ make
[email protected] $ sudo make install

設定ファイルのコピー

[email protected] $ mkdir -p ~/.config/onedrive
[email protected] $ cp ./config ~/.config/onedrive/config

デフォルトの設定ファイルはつぎのようになっている。

# Directory where the files will be synced
sync_dir = "~/OneDrive"
# Skip files and directories that match this pattern
skip_file = ".*|~*"

サービスの起動

[email protected] $ systemctl --user enable onedrive
[email protected] $ systemctl --user start onedrive

初回起動

サービスとして起動したら、onedrive コマンドを実行。

[email protected] $ onedrive

すると、端末にメッセージが表示される。「Authorize this app visiting:」につづいて URL が表示されるので、これをコピーしてブラウザでアクセスし、Microsoftアカウントにログインする。アプリから OneDrive へのアクセスを許可するかと聞かれるので「はい」を選択。新しい、空白のページが表示されるので、このページの URL をコピーして端末に戻り、「Enter the response uri:」のあとに貼り付けてエンター。これでファイルの同期が始まる。

自動起動の設定

ファイルの同期を続けるためには、onedrive コマンドを実行しておく必要があるらしい。Ubuntu にログインするときに自動的に実行するように設定する。

Alt+F2 キーを押してアクティビティ画面を表示し、「gnome-session-properties」を検索。出てきたアイコンをクリックすると「自動的に起動するプログラムの追加」ウィンドウが表示される。ここに onedrive -m コマンドを追加する。

参考ページ

 cf. UbuntuでOneDriveを使う – Qiita

カテゴリー: Misc, Ubuntu, Windows | コメントする

WordPressをやめて静的サイトジェネレータに乗り換えようかと考え始めた

きっかけは Qiita のこの記事を読んで。

 cf. 7年間使ってきたWordPressを捨ててContentful+Gatsby+Netlifyにしたら爆速になったし経緯とか教訓とか語る – Qiita

正直、Contentful も Gatsby も Netlify もどういうものかよく分かってないんだけど、WordPress に不満が溜まってきたからだ。

これ以上は後で書く。

カテゴリー: Misc | コメントする

UbuntuのNode.jsを最新にする

ここのところ JavaScript を書く機会があって、最近の書き方なんかを調べたりしてるんだけど、そういえば Ubuntu にインストールした Node.js はどうなってるんだっけかな、と思って確かめてみたら:

[email protected] $ node -v
v4.2.6

もはや、いつインストールしたのかもわからない古いバージョンだった。公式サイトによると、最新版が13.6.0、推奨版が12.14.1 LTS だ。

で、さて、バージョンアップはどうやったらいいのか。ググってみたら、n package というのを使うといいらしい。

 cf. Ubuntuに最新のNode.jsを難なくインストールする – Qiita

さっそくこの通りにやってみる。まずは npm で n package をインストール。

[email protected] $ sudo npm install n -g

その n package (nコマンド)を使って Node.js をインストール。

[email protected] $ sudo n stable

もとから入っていた古い Node.js を削除。

[email protected] $ sudo apt purge -y nodejs npm

そしてシェルを読みなおす。

[email protected] $ exec $SHELL -l

これで完了。最新になっているか、確かめてみよう。

[email protected] $ node -v
v12.14.1
[email protected] $ npm -v
6.13.4

Qiita の記事によると、複数バージョンの管理なんかもできるらしい。

カテゴリー: JavaScript, Ubuntu | コメントする

使わなくなった外付けHDDのデータを消去する

年末にサーバを1台止めたので、そこに繋いでいた外付け HDD を使わなくなった。1TB の HDD で、もう使いみちもなさそうだから処分しようと思う。というわけで、中のデータを完全消去することにした。

Ubuntu (というか Linux?)には、shred というコマンドがある。ファイルやディスクにランダムデータやゼロを書き込んで、データを消去、復元できなくするコマンドだ。

処分予定の HDD を Ubuntu マシンに繋いでみると、つぎのようになった。

[email protected] $ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0 931.5G  0 disk 
├─sda1   8:1    0   512M  0 part /boot/efi
├─sda2   8:2    0 927.1G  0 part /
└─sda3   8:3    0   3.9G  0 part [SWAP]
sdb      8:16   0 931.5G  0 disk 
└─sdb1   8:17   0 931.5G  0 part /media/takatoh/805ec9ee-d5ae-4894-95b2-cea22ab0
sr0     11:0    1  1024M  0 rom

sdb が対象の HDD だ。このディスクのデータを消去するにはつぎのようにする。

[email protected] $ sudo shred -uvz /dev/sdb

デフォルトでは、ランダムデータを書き込むことを3回繰り返す。指定したオプションの意味はつぎの通り。

  • -u 上書き後にファイルを消去
  • -v コマンド実行中の詳細(進捗)を表示
  • -z ランダムデータ書き込み後にゼロを書き込む

というわけで、今回のケースでは都合4回書き込むことになるんだけど、昨日の夜に始めて約12時間くらいが経過した今朝の段階でやっと2回目の書き込みが始まったところ。予想以上に時間がかかりそうだなぁ。

カテゴリー: Misc, Ubuntu | コメントする

Pythonで全文検索を実装してみた

JavaScript でやってるのを見かけたので。

 cf. JavaScriptで全文検索(N-gram)を実装してみる! – Simple is Beautiful.

アルゴリズムは N-gram っていう方法のうちでも簡単な uni-gram っていうみたい。詳しくはリンク先の記事を見て。

記事の説明を読んで、なんとなく理解したので Python で書いてみた。リンク先の JavaScript の実装はファイル名を参考にしたくらいで、ちゃんと読んでない。

できたのはこんな感じ。

  • create_index.py でインデックスを作って、search.py で検索
  • 検索対象のファイルはテキストファイルのみ。documents ディレクトリに入ってる
  • インデックスファイルは indexes ディレクトリ内につくる
  • document ID とファイル名の対応は docs.json ファイル

インデックスを作る create_index.py

from unigram import document
import json
import os


DOC_DIR = 'documents'
INDEX_DIR = 'indexes'
DOC_DATA = 'docs.json'


files = [os.path.join(DOC_DIR, f) for f in os.listdir(DOC_DIR)]
docs = {}
doc_id = 0
for file in files:
    with open(file, 'r') as f:
        text = f.read()
        tokens = document.tokenize(text)
        index = document.classify(tokens)
        document.save_index(index, doc_id, INDEX_DIR)
    docs[str(doc_id)] = {'name': os.path.basename(file), 'path': file}
    doc_id += 1

with open(DOC_DATA, 'w') as f:
    json.dump(docs, f, indent=2)

検索コマンド search.py

from unigram import document
import json
import os
import sys


INDEX_DIR = 'indexes'
DOC_DATA = 'docs.json'


string = sys.argv[1]

with open(DOC_DATA, 'r') as f:
    docs = json.load(f)
fcount = len(docs)

index_files = list(map(lambda x: os.path.join(INDEX_DIR, x), os.listdir(INDEX_DIR)))
index = {}
for file in index_files:
    c = chr(int(os.path.basename(file).replace('.index', '')))
    with open(file, 'r') as f:
        index[c] = document.parse_index(f.read())

m = list(map(lambda x: index[x], list(string)))

for i in range(fcount):
    doc_id = str(i)
    if not all(map(lambda x: doc_id in x.keys(), m)):
        continue
    n = list(map(lambda x: x[doc_id], m))
    s = set(n[0])
    for s1 in n[1:]:
        s = set(list(map(lambda x: x + 1, s)))
        s = s & set(s1)
    if len(s) > 0:
        pos = list(map(lambda x: x - len(string) + 1, s))
        pos.sort()
        print(docs[doc_id]['name'], pos)

両方から使うモジュール unigram/document.py

import os


def tokenize(text):
    return list(text)


def classify(token_list):
    tokens = {}
    pos = 0
    for t in token_list:
        if not t in tokens:
            tokens[t] = []
        tokens[t].append(pos)
        pos += 1
    return tokens


def save_index(index, doc_id, index_dir):
    for c, idx in index.items():
        l = str(doc_id) + ':' + ','.join(list(map(lambda x: str(x), idx))) + '\n'
        with open(os.path.join(index_dir, str(ord(c)) + '.index'), 'a') as f:
            f.write(l)


def parse_index(content):
    l = content.split('\n')
    l.pop()
    index = {}
    for l2 in l:
        a = l2.split(':')
        index[a[0]] = [int(x) for x in a[1].split(',')]
    return index

とにかくまずは動くものを、ってことで作ったので、コードが整理されてないのは目を瞑ってほしい(後で直す)。

検索対象ファイルのサンプルには、別のプロジェクトで書いた Ruby のソースファイル。

[email protected] $ ls documents
Gemfile       Rakefile  boot.rb    config.yaml
Gemfile.lock  app.rb    config.ru  config.yaml.example

インデックスを作る。

[email protected] $ python create_index.py

できたインデックスファイルがこれ。

[email protected] $ ls indexes
10.index   111.index  123.index  44.index  58.index  71.index  84.index
100.index  112.index  124.index  45.index  60.index  72.index  85.index
101.index  113.index  125.index  46.index  61.index  73.index  87.index
102.index  114.index  126.index  47.index  62.index  74.index  89.index
103.index  115.index  32.index   48.index  63.index  75.index  91.index
104.index  116.index  34.index   49.index  64.index  76.index  93.index
105.index  117.index  35.index   50.index  65.index  77.index  95.index
106.index  118.index  36.index   51.index  66.index  78.index  97.index
107.index  119.index  39.index   52.index  67.index  79.index  98.index
108.index  120.index  40.index   53.index  68.index  80.index  99.index
109.index  121.index  41.index   55.index  69.index  82.index
110.index  122.index  43.index   56.index  70.index  83.index

「require」という文字列を検索してみる。ファイル名と出現位置(のリスト)が出力される。

[email protected] $ python search.py require
boot.rb [0, 17]
Rakefile [0, 15, 32, 71]
config.ru [0]
app.rb [0, 23, 40, 56, 71]

大丈夫そうだ。

カテゴリー: Python, アルゴリズム | コメントする

MyDNSに独自ドメインを設定してみる

マイIPが遅いので、何か別の方法はないかと調べていたところ、別のサーバで使っている MyDNS が独自ドメインも使えるということが分かった。

MyDNS を使っているのは、WiMAX でインターネットに接続してるサーバだ。WiMAX はグローバルアドレスを付与してくれるサービスがあるけど、そのアドレスは固定ではないので DDNS の MyDNS を使っていたわけ。で、これを使い始めた時には、無料で使えるのは MyDNS のサブドメインだけだと思ったんだけど、いま調べたら独自ドメインでも無料で使えるようだ。早速試してみよう。

MyDNS のドメイン登録情報を変更する

独自ドメインのホスト名を仮に server3.panicblanket.com としよう。

MyDNS にログインして、DOMAIN INFO のページに移動する。このページで Domain、MX、Hostname を新しいホスト名に合わせて書き換えて、変更を反映させる。

つぎに、サーバのほうで、IP アドレスを通知するスクリプトを実行して、実際に使っているアドレスを通知する。

さくらインターネットでゾーン編集

ドメイン自体はさくらインターネットで管理しているので、server3.panicblanket.com だけ、MyDNS のネームサーバを参照するように編集する。

具体的には、ゾーン編集の画面でつぎのように設定する。

  • エントリ名: server3.panicblanket.com
  • 種別: NS
  • 値: ns0.mydns.jp.

ns0.mydns.jp は MyDNS のネームサーバ。最後に . (ドット)をつけるのを忘れないこと。server3.panicblanket.com の名前解決には ns0.mydns.jp を参照しろってことだな。

さて、これで設定は完了のはず。

結果

新しい名前で ping もとおるし、ssh での接続もできるようになった。大丈夫のようだ。

カテゴリー: Misc | コメントする

マイIPは遅い

先日、インターリンク社のマイIPサービスを使って固定IPアドレスを割り当てたわけだけど、はっきり言って通信速度が遅い。どのくらい遅いか、マイIPを使わない場合と比べてみた。

  • マイIPなし: 770Mbps,アップロード 560Mbps
  • マイIPあり: 5.9Mbps、 アップドード 5.6Mbps

通信速度は fast.com ってページで測った。マイIP経由だと約1/100だ。何度か測ってみたけどだいたいこのオーダー。これじゃせっかくの NURO光回線(下り2Gbps,上り1Gbps)がもったいない。

そりゃもちろん、VPN を介してインターリンク社のネットワークを経由するんだから、その分遅くなるのは承知してたけど、これほどとは。これは何かほかの方法を考えるかなぁ。

[追記]

インターリンクの FAQ に通信速度について書いてあった。曰く:

実際の通信速度は弊社のマイIPサーバーとお客様のPCとの間の接続環境によって変化します。
弊社ではおよそ 2Mbps~4Mbpsと推測しております。

マイIPサービスの通信速度はどれくらいですか? – インターリンク FAQ

だいたい実測通りだ。さきに言ってよ……(いや、見つけられなかったオレが悪いんだけどさ)。

カテゴリー: Misc | コメントする

インターリンクのマイIPサービスでCentOS8マシンに固定IPアドレスを割り当てる

インターリンクのマイIPサービス

NURO光は固定IPアドレスを割り当てるサービスを提供していないので、インターリンク社のマイIPというサービスを使って固定IPアドレスを割り当てる。

 cf. INTERLINK

上のページから、マイIPサービスに申し込んだ。申し込み自体は何も難しくはない。クレジット払いにしたのですぐに利用できるようになる。

問題はここから。マイIPサービスは、VPN を使って PC とインターリンクのサーバを繋ぎ、PC の ppp0 インターフェイスに固定IPアドレスを割り当てるようになっている(ようだ)。そのためには PPTP クライアントの設定が必要なんだけど、これでハマった。

環境

まずは環境を整理しておこう。

  • OS: CentOS 8.0
  • マイIPに必要な情報は取得済み

設定作業(1)

インターリンクの公開しているマニュアルに沿って作業する。

 cf. https://faq.interlink.or.jp/faq2/View/wcDisplayContent.aspx?id=501

マイIP接続ツールをダウンロードして /etc 以下に展開。

[[email protected] ~]$ curl -O https://www.interlink.or.jp/support/vpn/myip/myiptools/myiptools.tar.gz
[[email protected] ~]$ sudo tar xvzf myiptools.tar.gz -C /etc

設定ファイル /etc/myip/myip.conf を自分の接続情報に合わせて編集。

[[email protected] ~]$ sudo vim /etc/myip/myip.conf

初期設定スクリプトを実行。

[[email protected] ~]$ sudo /etc/myip/myip-setup

ここでエラーが起きた。メッセージを抜粋する。

一致した引数がありません: pptp-setup
エラー: 一致するものが見つかりません
/etc/myip/myip-setup: 行 111: pptpsetup: コマンドが見つかりません
/etc/myip/myip-setup: 行 117: /etc/ppp/peers/myip_miXXXXXX: そのようなファイルやディレクトリはありません

myip_miXXXXXX っていうファイルは自分用の設定ファイル(実際には miXXXXXX の部分に自分のログインIDが入る)。

初期設定スクリプト myip-setup の中を覗いてみて分かったのは、pptp-setup っていうパッケージをインストールしようとしているけどそれが失敗しているということと、そのせいか pptpsetup コマンドが見つからないようだ、ってことだ。

じゃあ、手動で pptp-setup パッケージをインストールしてやればいいかというと、そんなパッケージは無いらしい。

[[email protected] ~]$ dnf search pptp-setup
一致する項目はありませんでした。

というところまでが昨日の話。

設定作業(2)

今日になっていろいろググってみたところ、PPTP Client の公式サイトを見つけた。

 cf. http://pptpclient.sourceforge.net/

このページの Download セクションには、pptp には pptpsetup が含まれている、と書いてある。

pptp, the helper program used by pppd to make a tunnel, which also includes pptpsetup,

なら、ここからダウンロードして pptpsetup をコピーしてやったらいいんじゃないか。というわけで早速ダウンローとして展開。するとたしかに含まれていた。

[[email protected] ~]$ wget https://sourceforge.net/projects/pptpclient/files/pptp/pptp-1.10.0/pptp-1.10.0.tar.gz
[[email protected] ~]$ tar xzvf pptp-1.10.0.tar.gz
[[email protected] ~]$ ls pptp-1.10.0
AUTHORS            dirutil.c        pptp_compat.h   routing.c
COPYING            dirutil.h        pptp_ctrl.c     routing.h
ChangeLog          options.pptp     pptp_ctrl.h     test-redirections.c
DEVELOPERS         orckit_quirks.c  pptp_gre.c      test-redirections.h
Documentation      orckit_quirks.h  pptp_gre.h      util.c
INSTALL            ppp_fcs.c        pptp_msg.h      util.h
Makefile           ppp_fcs.h        pptp_options.h  vector.c
NEWS               pptp.8           pptp_quirks.c   vector.h
PROTOCOL-SECURITY  pptp.c           pptp_quirks.h   vector_test.c
README             pptp_callmgr.c   pptpsetup       version.c
TODO               pptp_callmgr.h   pqueue.c        version.h
USING              pptp_compat.c    pqueue.h

この pptpsetup、中を覗いてみると Perl のスクリプトのようだ。/usr/sbin にコピーして実行権限をつけてやる。

[[email protected] ~]$ sudo cp pptp-1.10.0/pptpsetup /usr/sbin
[[email protected] ~]$ sudo chmod 755 /usr/sbin/pptpsetup

さあ、これでどうだろう。初期設定スクリプトを実行。

[[email protected] ~]$ sudo /etc/myip/myip-setup
CentOS-8 - AppStream                            2.0 kB/s | 4.3 kB     00:02    
CentOS-8 - Base                                 3.2 kB/s | 3.9 kB     00:01    
CentOS-8 - Extras                               673  B/s | 1.5 kB     00:02    
Package gawk-4.2.1-1.el8.x86_64 is already installed.
Package sed-4.5-1.el8.x86_64 is already installed.
依存関係が解決しました。
行うべきことはありません。
完了しました!
/sbin/pptpsetup: can't write to '/etc/ppp/peers/myip_miXXXXXX': No such file or directory
/etc/myip/myip-setup: 行 117: /etc/ppp/peers/myip_miXXXXXX: そのようなファイルやディレクトリはありません
done.

pptpsetup コマンドは実行できたようだけど、ファイルが書き込めないといっている。調べてみると /etc/ppp/peers ディレクトリが無いようなので作ってやる。

[[email protected] ~]$ sudo mkdir /etc/ppp/peers

こんどはどうだ。

[[email protected] ~]$ sudo /etc/myip/myip-setup
メタデータの期限切れの最終確認: 0:01:04 時間前の 2019年12月15日 10時20分25秒 に実施しました。
Package gawk-4.2.1-1.el8.x86_64 is already installed.
Package sed-4.5-1.el8.x86_64 is already installed.
依存関係が解決しました。
行うべきことはありません。
完了しました!
done.

エラーなし。うまくいったようだ。これでやっと次にすすめる。

設定作業(3)

マニュアルによると:

PPTP接続に必要なTCPポート1723およびGREプロトコルを通過できるようにしておく必要があります。

と書いてあるけど、やり方が書いてない。ポートの開け方はわかる。

[[email protected] ~]$ sudo firewall-cmd --zone=public --add-port=1723/tcp --permanent

GREプロトコルの方はググったら↓のページを見つけた。

 cf. https://www.vultr.com/docs/how-to-establish-a-gre-tunnel-between-two-centos-7-servers
 cf. https://github.com/firewalld/firewalld/issues/30

ip_gre モジュールをロードする。

[[email protected] ~]$ modprobe ip_gre

GRE プロトコルを通過させるのは firewall-cmd でできるようだ。

[[email protected] ~]$ sudo firewall-cmd --zone=public --add-rich-rule='rule protocol value="47" accept' --permanent

さあ、これで準備は整ったはずだ。

接続開始

myip-up コマンドで接続を開始する。

[[email protected] ~]$ sudo /etc/myip/myip-up
Using interface ppp0
Connect: ppp0 <--> /dev/pts/1
CHAP authentication succeeded
MPPE 128-bit stateless compression enabled
local  IP address 202.241.129.128
remote IP address 202.241.128.1
private IP mode.
done.

ifconfig コマンドの出力(下はその抜粋)をみると、ppp0 インターフェイスに固定IPアドレスが割り振られているのがわかる。

ppp0: flags=4305  mtu 1346
        inet 202.241.129.128  netmask 255.255.255.255  destination 202.241.128.1
        ppp  txqueuelen 3  (Point-to-Point Protocol)
        RX packets 7  bytes 100 (100.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7  bytes 134 (134.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ちなみに、接続を終了するには /etc/myip/myip-down コマンドを実行する。

確認

別のネットワークに繋がってる Windows マシンから、http://202.241.129.128/hello.html にアクセスしたところ、ちゃんと「Hello, this is rollo.」と表示されるのを確認した(rollo ってのは VPN 接続したホストの名前)。

これにて無事完了。

[追記 12/16]

一昨日(12/14)、スクリプトがエラーになって先に進めなくなったところで、インターリンク社に問い合わせをしたんだけど、今日になってその回答が来た。曰く:

大変申し訳ございませんが、マイIPはCentOS 8.0に対応しておりません。

……まぁ、予想はしてたけどね。リリースされたばっかりのディストリビューションだしね。

それに、パッケージが無かったりすりのはディストリビューションの方の問題であって、インターリンク社が悪いわけではない。

ともかく、CentOS 8.0 でマイIPサービスを使おうという人がいたら、上に書いた方法でうまくいったということを参考にしてもらおう。

カテゴリー: CentOS, Misc | コメントする