今回実際に構築するもの
PPPoEサーバーの構築は、多くのシステム管理者が関わることのないレイヤーで行われる作業です。セッションネゴシエーション、IPプール管理、プロトコルレベルでのユーザー単位の認証——これらは実際のISPインフラの運用の核心です。小規模なISP、キャンパスネットワーク、またはキャリアグレードの環境を模倣したラボを構築しようとしているなら、まさにこういった作業に取り組むことになります。
私は実際に本番環境でこれを運用しました。マネージドネットワーク上で150の同時PPPoEセッションを処理するaccel-pppをローカル認証で動かしたのですが、1年以上にわたって大きな手を加えることなく稼働し続けました。後からRADIUSを追加してユーザー管理を集中化した際も、切り替えは半日もかからず、既存のセッションへの影響もありませんでした。
アプローチの比較
LinuxでのPPPoEにおいては、主に3つのツールが主流です。どれが適しているかは、セッション数と運用の複雑さをどこまで許容できるかによって変わります。
選択肢1: rp-pppoe(クラシックなpppoe-server)
rp-pppoeは、LinuxのpppdデーモンをラップしたオリジナルのユーザースペースPPPoEサーバーです。各セッションごとに専用のpppdプロセスが生成されるため、ユーザー数が少なければ問題ありませんが、負荷がかかると途端に破綻します。設定は/etc/ppp/options、chap-secrets、pppoe-serverの起動フラグに分散しています。認証はローカルのPAP/CHAPまたはRADIUS経由で行われます。デバッグは複数のプロセスのログを同時に追いかける必要があり、手間がかかります。
選択肢2: accel-ppp
accel-pppはカーネルアクセラレーション対応のマルチプロトコルアクセスサーバーです。PPPoE、L2TP、PPTPを単一のデーモンで一元管理できます。セッションはカーネル空間で処理されるため、rp-pppoeのプロセス単位モデルでは到底届かないスループットを実現できます。RADIUSサポート、TCP管理CLI、IPプール設定、セッション単位のレート制限が標準で搭載されています。テストラボ以上の用途には、これが正しい選択です。
選択肢3: RouterOS VM
MikrotikのRouterOSをVMとして動かし、PPPoEコンセントレーターとして使うチームもあります。チームがすでにRouterOSを知っているなら学習コストは低くなりますが、PPPoEのためだけにOSを丸ごと管理することになり、ライセンスコストもかかります。Linuxネイティブのスタックであれば、accel-pppが同じ役割をはるかに少ないオーバーヘッドでこなしてくれます。
メリットとデメリット
rp-pppoe
- メリット: セットアップが簡単、ドキュメントが豊富、標準の
pppdで動作、プロトコルを学ぶのに最適 - デメリット: セッションごとにOSプロセスが1つ必要(大規模ではCPU負荷が高い)、設定が複数ファイルに分散、ライブセッションの管理が難しい、同時接続100ユーザー前後で限界に達する
accel-ppp
- メリット: カーネルアクセラレーション、単一デーモン、RADIUSクライアント内蔵、数千セッションにスケール可能、CLIによるライブセッション管理、レート制限(シェーパー)が標準搭載
- デメリット: ほとんどのディストリビューションでソースからのコンパイルが必要、カーネルモジュールへの依存、rp-pppoeよりドキュメントが少ない
RouterOS VM
- メリット: GUI管理、Mikrotik経験者には馴染みやすい
- デメリット: ライセンスコスト、フルVMのリソースオーバーヘッド、Linuxのツールチェーンと相性が悪い
推奨構成
小規模なテスト以上の用途にはaccel-pppを使いましょう。カーネルレベルのセッション処理だけでも、多少手間がかかるビルドに見合う価値があります。認証は最初にローカルのchap-secretsから始め、ユーザー管理の集中化やユーザー単位のプラン適用が必要になったらFreeRADIUSに移行しましょう。
推奨スタック:
- PPPoEコンセントレーターとしてaccel-ppp
- 開発・小規模環境のローカル認証(
/etc/ppp/chap-secrets) - 複数ユーザーやプラン管理が必要な本番環境にはFreeRADIUS
- アップリンクへのNATにはiptables MASQUERADE
- 自動起動・障害時の再起動にはsystemdサービス
実装手順
ステップ1: accel-pppのビルドとインストール
accel-pppはほとんどのディストリビューションのリポジトリに含まれていないため、ソースからコンパイルします:
# ビルド依存パッケージのインストール (Ubuntu/Debian)
sudo apt update && sudo apt install -y cmake libpcre3-dev libssl-dev \
libevent-dev libcurl4-openssl-dev git build-essential
git clone https://github.com/accel-ppp/accel-ppp.git
cd accel-ppp
mkdir build && cd build
cmake -DKDIR=/usr/src/linux-headers-$(uname -r) \
-DCMAKE_INSTALL_PREFIX=/usr \
-DRADIUS=TRUE \
..
make -j$(nproc)
sudo make install
カーネルモジュールをロードし、再起動後も有効になるよう設定します:
sudo modprobe pppoe
echo "pppoe" | sudo tee -a /etc/modules
ステップ2: accel-pppの設定
すべての設定は/etc/accel-ppp.confに記述します。動作する基本設定の例を示します:
[core]
thread-count=4
log-error=/var/log/accel-ppp/core.log
[modules]
log_file
pppoe
auth_mschap_v2
auth_chap_md5
auth_pap
ippool
shaper
[log]
log-file=/var/log/accel-ppp/accel-ppp.log
log-emerg=/var/log/accel-ppp/emerg.log
copy=1
[pppoe]
interface=eth1 # クライアント側(アクセス側)のインターフェース
ac-name=MyISP
service-name=internet
verbose=1
[dns]
dns1=8.8.8.8
dns2=1.1.1.1
[ip-pool]
gw-ip-address=10.10.0.1 # 各セッションのサーバー側に割り当てるIP
10.10.1.0/24 # クライアントIPプール
10.10.2.0/24
[ppp]
mtu=1492
mru=1492
ccp=0
min-mtu=1280
unit-priv=1
[auth]
chap-secrets=/etc/ppp/chap-secrets
[cli]
verbose=1
mode=tcp
port=2000
timeout=0
sudo mkdir -p /var/log/accel-ppp
sudo chown nobody:nogroup /var/log/accel-ppp
ステップ3: ローカル認証用ユーザーの追加
chap-secretsは標準的なpppd形式を使用します。4列目に特定のIPを指定するか、*を使ってプールから割り当てます:
# /etc/ppp/chap-secrets
# クライアント サーバー シークレット IPアドレス
user1 * password123 *
user2 * securepass *
admin * adminpass 10.10.1.10 # 固定IP
このファイルには平文の認証情報が含まれているため、アクセス権を制限してください:
sudo chmod 600 /etc/ppp/chap-secrets
sudo chown root:root /etc/ppp/chap-secrets
ステップ4: IPフォワーディングとNATの有効化
PPPoEクライアントはすべてのトラフィックをサーバー経由でルーティングするため、フォワーディングを有効にする必要があります。eth0はご自身のアップリンクインターフェースに置き換えてください:
sudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
# インターネットアクセス用NAT
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# 大容量転送時のMTU問題を防ぐためMSSをクランプ
sudo iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
-j TCPMSS --clamp-mss-to-pmtu
# ルールを永続化
sudo apt install iptables-persistent
sudo netfilter-persistent save
ステップ5: systemdサービスの作成と起動
cat <<EOF | sudo tee /etc/systemd/system/accel-ppp.service
[Unit]
Description=accel-pppアクセスサーバー
After=network.target
[Service]
ExecStart=/usr/sbin/accel-pppd -c /etc/accel-ppp.conf
Restart=on-failure
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now accel-ppp
sudo systemctl status accel-ppp
ステップ6: クライアント接続のテスト
eth1と同じレイヤー2セグメントにあるLinuxマシンから:
sudo apt install pppoe
# PPPoEクライアント接続の設定
sudo pppd plugin rp-pppoe eth0 \
user "user1" \
password "password123" \
noauth defaultroute usepeerdns persist
# PPPインターフェースが起動しているか確認
ip addr show ppp0
ip route show
次にサーバー側に戻り、セッションが登録されているか確認します:
sudo accel-cmd show sessions
# アクティブセッション、割り当てIP、ユーザー名、送受信バイト数
本番環境でのFreeRADIUSへの移行
ローカル認証は小規模環境では十分に機能します。ユーザー数が増えてきたらFreeRADIUSに切り替えましょう。FreeRADIUSをインストールしてユーザーを定義した後、accel-ppp.confの[modules]を更新し、[radius]ブロックを追加します:
[modules]
log_file
pppoe
radius
ippool
shaper
[radius]
server=127.0.0.1,secret=your_radius_secret,auth-port=1812,acct-port=1813
dae-server=127.0.0.1:3799,secret=your_radius_secret
timeout=3
max-try=3
acct-timeout=120
verbose=1
ローカルの[auth]ブロックは完全に削除してください。FreeRADIUSがそれ以降のすべての認証を担当します。ユーザー単位の帯域制限を適用する場合は、WISPr-Bandwidth-Max-UpとWISPr-Bandwidth-Max-DownをRADIUS属性として送信します。これは商業ISPが加入者のスピードプランを制御するのに使っているのと同じ仕組みです。
ライブセッションの管理
セッション管理に再起動は不要です。accel-pppにはTCP CLIが付属しており、すべてのアクティブな接続をリアルタイムで制御できます:
# 管理インターフェースへの接続
sudo accel-cmd
# CLI内の便利なコマンド:
show sessions
show sessions username user1
show stat
terminate username user1
terminate ip 10.10.1.15
ハマりやすいポイント
実際の運用経験から、本番稼働前に知っておくべきことをいくつか紹介します:
- MTUミスマッチによる不可解な障害: PPPoEは8バイトのオーバーヘッドを追加するため、有効なMTUが1500から1492に下がります。小さなパケットは問題ありませんが、大きなファイル転送は途中で止まったり完全に失敗したりします。ステップ4のMSSクランプがほとんどのケースをカバーしますが、クライアント側のインターフェースMTUも明示的に1492に設定してください。
- カーネルモジュールの未ロード: セッションがまったく確立しない場合は
lsmod | grep pppoeを実行してください。カーネルによってはppp_genericやppp_asyncも手動でロードする必要があります。 - インターフェースが間違ったセグメントにある:
pppoe interface=の設定はクライアントと同じレイヤー2ブロードキャストドメインにある必要があります。クライアントがVLAN上にある場合は、まずVLANサブインターフェース(eth1.100など)を作成し、物理インターフェースではなくそちらをaccel-pppに指定してください。 - 大規模環境でのファイルディスクリプタ制限: セッションごとにファイルディスクリプタを消費します。systemdユニットの
LimitNOFILE=65535がこれを自動的にカバーします。デーモンを手動で起動する場合は、起動前にシェルでulimit -n 65535を設定してください。

