概要
筆者は、P2P型掲示板の一つ「新月 - P2P匿名掲示板」の公式ノード実装sakuをFreeBSD上で運用しています。
FreeBSDでのsaku導入・運用方法を備忘録として残します。
GNU/Linuxや他UNIX系OSなどでもある程度参考にできるかもしれません。
新月 - P2P匿名掲示板とは
2003年8月29日にfukutommy氏が発表した、オープンソースのP2P掲示板です。
新月プロトコルにしたがって互いに通信するノード群が新月ネットワークを構成しています。
ユーザはソフトウェアを実行してノードとして参加したり、公開ゲートウェイと呼ばれるノードを利用したりして投稿や閲覧ができます。
公式の公開ゲートウェイ
現在はsakuが公式の実装として開発されています。他にもGouなどいくつかの実装があります。
2023年8月で発表から20年が経ちますが、現在(2023年7月)もおよそ10~20個のノードが運用中です。
筆者の環境
さくらインターネットのさくらのVPS 1GBプランを使用しています。
OSはFreeBSD 13.2です。
VPSにFreeBSDインストール
さくらインターネットでは以前はコントロールパネルからカスタムOSインストールでFreeBSDをインストールできましたが、現在はISOイメージから起動が必要なようです。
サーバのセキュリティ設定
saku導入前にセキュリティ設定をします。
やらなくても運用できますがセキュリティ上実施したほうがベターです。
- sudo権限付き管理者ユーザ作成(rootユーザはなんでもできてしまうため危険)
- sshのrootログイン無効化(外部の攻撃者が直接rootにログインするのを防ぐ)
- sshで公開鍵認証のみにする(パスワード認証よりもセキュア)
- OSパッケージアップグレード(脆弱性対策等のため。運用中は定期的に必要。アップグレード後はOS再起動することで各種サービス等も新しいバージョンとなる)
- etc.
パッケージ導入
Gitインストール(必要な場合)
$ sudo pkg install git
Pythonインストール
デフォルトのPython 3.9(2023年7月9日現在)で問題ない場合は不要です。筆者はPython3.11を導入しています。
FreeBSDのパッケージは全般的にそうですがportsのほうがバージョンが新しいと思います。もしくはpython.orgからソースコードをダウンロードしてビルドでもよさそうです。
$ sudo pkg install py311 # pkg
$ sudo portmaster lang/py311 # portmaster
pipインストール
$ python3 -m ensurepip
saku導入
sakuダウンロード
sakuをダウンロードします。Gitでリポジトリをクローンする方法と、リリースされているファイルをダウンロードする方法があります。
Gitリポジトリクローン
$ git clone https://github.com/shingetsu/saku.git
最新コミットはリリース済みのバージョンより進んでいることがあるため、安定版で運用したい場合はバージョンのタグ付きコミットへ移動します。
$ git checkout release-4.11.0
公式サイトよりダウンロード
以下ページから最新の安定版もしくは不安定版をダウンロードします。
ダウンロード後、適当なディレクトリに展開します。
sakuをインストールする場合
朔のインストールする場合の手順を参考にインストールできると思います。
筆者はインストールしていないため省略します。
sakuをインストールしない場合
pipenv導入
v4.10.0以降のsakuは実行時にpipenvを使います。pipでインストールできます。
$ pip install pipenv
w3mインストール
サーバにてsakuの画面へアクセスする際利用できるコマンドライン用Webブラウザです。
$ sudo pkg install w3m
saku設定
saku.ini
sakuの基本の設定です。設定ファイルとして以下を読み込みます。下にいくほど設定が優先されます。
file/saku.ini
/usr/local/etc/saku/saku.ini
/etc/saku/saku.ini
~/.saku/saku.ini
例
[Network]
port: 8000
dnsname: example.com
[Gateway]
visitor: .
admin: ^127
friend: ^127
[Application Thread]
save_record: 0
save_removed: 0
get_range: 32140800
sync_range: 32140800
設定のパラメータ一覧(v4.11.0)
Networkセクション
名前 | デフォルト値 | 説明 |
---|---|---|
port | 8000 | listenするポート |
dat_port | 8001 | 2ch interfaceのlistenするポート |
dnsname | /server.cgiへのdnsname以外のアクセスをブロックする。ドメイン名でのアクセスをOKにしてIPアドレスはNGにするイメージ。v4.11.0で追加 | |
max_connection | 20 | 最大コネクション数 |
Pathセクション
名前 | デフォルト値 | 説明 |
---|---|---|
docroot | ./www | |
log_dir | ./log | |
run_dir | ../run | |
file_dir | ../file | |
cache_dir | ../cache | |
template_dir | ../template | |
spam_list | ../file/spam.txt | |
initnode_list | ../file/initnode.txt | |
node_allow | ../file/node_allow.txt | |
node_deny | ../file/node_deny.txt | |
apache_docroot | /var/local/www/shingetsu | |
archive_dir | /var/local/www/archive |
Gatewayセクション
/gateway.cgiに関する設定です。
名前 | デフォルト値 | 説明 |
---|---|---|
admin | ^127 | 管理者用機能を使えるIPアドレス(正規表現可) |
friend | ^127 | スレッド新規作成機能などを使えるIPアドレス(正規表現可) |
visitor | . | 画面を見られるIPアドレス(正規表現可)。「.」にすると誰でも閲覧可(=公開ゲートウェイ)になる。 |
server_name | サーバ名とポート番号。例:example.com:8000 | |
gateway_protocol | http | httpsかhttp |
tag_size | 20 | タグの最大数 |
rss_range | 259200 | RSSの範囲。3*24*60*60(秒) |
top_recent_range | 259200 | トップページrecentnの表示範囲。3*24*60*60(秒) |
recent_range | recentページの表示範囲。2678400 | 31*24*60*60(秒) |
record_limit | 2048 | レコードのサイズ制限(kB) |
proxy_destination | proxy_destination | プロキシサーバのサーバ名とポート。例:example.com:8000 |
archive_uri | https://archive.shingetsu.info/ | |
enable2ch | False | 2ch interface |
root_index | gateway.cgi | rootのインデックス |
Application Threadセクション
名前 | デフォルト値 | 説明 |
---|---|---|
save_record | 0 | レコード保持期間(秒)。0は無制限 |
save_size | 1 | save_recordの期間経過後、最低限保持するレコードの個数 |
get_range | 2678400 | 初回取得時の取得範囲。0は無制限。31*24*60*60(秒) |
sync_range | 864000 | 定期取得時の取得範囲。0は無制限。10*24*60*60(秒) |
save_removed | 4320000 | 50*24*60*60(秒) |
page_size | 50 | ページのレコード表示数 |
thumbnail_size | None | サムネイルを作る。PIL.Imageライブラリが必要。最大幅x最大高で指定。例:400x400 |
force_thumbnail | False |
spam.txt
スパムフィルタです。正規表現で記述できます。
1行目でファイルの文字コードを指定します。
例
# -*- coding: utf-8 -*-
#
# Regexp list for spam posts.
# Copyright (c) 2006,2014 shinGETsu Project.
#
# Encoding must be UTF-8.
#
# Write one regexp per one line.
# The regexp is tested for a record line.
#
# Example:
# <>body:This is SPAM
# [Tt]his is (SPAM|Spam)
# This.*Spam
#
<>mail:[^@]+@[^.]+\..+
<>body:[ -~]<>mail:[ -~]+<>name:[ -~]+$
initnode.txt
初期ノードです。
node_allow.txt
node_deny.txt
隣接ノードや探索ノードとして登録しないノードです。
version.txt
Gitで運用している場合、コミットのタイムスタンプをサーバの返すレスポンスのヘッダ情報に付与できます。
例:shinGETsu/0.7 (Saku/4.11.0; git/20230612-0010) Python/3.11.4
$ make version
$ cat file/version.txt
20230612-0010
運用方法
saku起動(pipenv版)
$ pipenv --python /usr/local/bin/python3.11 install
$ nohup pipenv --python /usr/local/bin/python3.11 run python3.11 ./saku.py --silent > /dev/null 2>&1 &
saku停止(pipenv版)
$ p_id=$(ps | grep "./saku.py" | grep -v grep | awk '{print $1}')
$ kill $p_id
サーバのステータス
Statusページでノード情報を参照できます。
Known Nodesがページ閲覧時点の新月ネットワークノード数とおおよそ等しくなります。
Linked Nodes 6
Known Nodes 10
BBSes 60
Articles 3966
Cache Size 6.4MB
Self node node0.example.com:8000/server.cgi
Linked Nodes
• node1.example.com:8000/server.cgi
Known Nodes
• node1.example.com:8000/server.cgi
• node2.example.com:8000/server.cgi
スレッド取得
管理者として自ノードに存在しないスレッドにアクセスするとネットワーク上から投稿を取得できます。
Recentページに他ノードで最近投稿があったスレッドがリストアップされています。
スレッド削除
削除したいスレッドにチェックを入れてDelete BBSをクリック
投稿削除
削除したい投稿にチェックを入れてDelete articleをクリック
sakuのバージョンアップ
設定ファイル等を編集していなければダウンロードして上書き更新で特に問題ないと思います。Gitでクローンしておくとgit pull
で最新版に更新できます。
依存パッケージのバージョンアップ
$ pip list --outdated # pipの更新されていないモジュールを出す
$ pip install --upgrade <モジュール名> # アップグレード
$ pipenv update # sakuの依存パッケージをバージョンアップ
注意点
投稿の完全な削除は難しい
自ノードの投稿は削除可能で削除通知を他ノードに出すこともできますが、実際に消すかは各ノード管理者の判断になります。
著作権侵害コンテンツ等に注意
公開ゲートウェイの場合は通常のWebサイトと同様に外部から閲覧できる状態になります。著作権侵害している投稿などは削除したり、そもそも怪しそうなスレッドは取得しないようにしたりする対策が必要と思います。
その他
- FreeBSD jailでコンテナ化もしてみたいです。
- 疑問点や運用での困り事は新月の開発や公開ゲートウェイ管理者会などで質問すると解決するかもしれません。
参考
設定ガイド
サンプル設定
デフォルト設定