短縮URLを独自ドメインで運用できる「Shlink」をインストール

Microsoft TeamsのURLが長いので短くできないものかと調べ、Shlinkをインストールしてみたときの覚書。

環境: CentOS Stream 9, nginx 1.22.1, PHP 8.1.8, shlink 3.5.1


1.Shlinkとは?

オープンソースの自前ホストにインストールして運用できる短縮URLシステム。
独自ドメインの短縮URLが生成可能になる。

ウェブ管理ツールのweb clientと分離されている。
web clientがなくてもコマンドラインで短縮URLの生成が可能。
web client自体もオープンソースで配布されている。

Shlink公式サイト/GitHubリポジトリ

PHP 8.1以上が必要。


2.Shlinkをソースからビルド(失敗)

あとで分かったけどアップデート機能があるのでgit cloneする必要はない。
参考: Shlink — The URL shortener — Documentation


まずはPHP Composerをインストール。
公式サイトを参考に。
参考: Composer

# php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
# php -r "if (hash_file('sha384', 'composer-setup.php') === '55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
# php composer-setup.php
# php -r "unlink('composer-setup.php');"
# mv composer.phar /usr/local/bin/composer

確認
# composer --version

Composer version 2.5.3 2023-02-10 13:23:52

ここからShlinkのビルド

GitHubのREADMEを参考にする。

積極的に開発が進められているのでソースからビルドしてみる。
# git clone https://github.com/shlinkio/shlink.git
# cd shlink/
# git tag
# git checkout v3.5.1

ビルドするスクリプト実行
# ./build.sh 3.5.1

エラーが表示された。

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - paragonie/sodium_compat v1.5.6 requires php ^5.2.4|^5.3|^5.4|^5.5|^5.6|^7 -> your php version (8.1.8) does not satisfy that requirement.
    - shlinkio/shlink-common v5.3.1 requires lcobucci/jwt ^4.1 -> satisfiable by lcobucci/jwt[4.2.0, 4.2.1, 4.3.0].
    - lcobucci/jwt[4.2.0, ..., 4.3.0] require ext-sodium * -> satisfiable by paragonie/sodium_compat[v1.3.0, ..., v1.18.1].
    - Root composer.json requires shlinkio/shlink-common ^5.3.1 -> satisfiable by shlinkio/shlink-common[v5.3.1].

依存関係でPHP7でないとだめらしい。
公式サイトに8.1以上と書いてあったのに…。

諦めてビルド済みをダウンロードすることにした。
一旦全削除
# cd ../
# rm -rf shlink/


3.shlinkをダウンロードしてインストール

公式サイトのドキュメントを見て進める。

unzipが必要
# dnf install unzip

ビルド済みをダウンロードして展開
# cd /home/httpd/
# curl -LO https://github.com/shlinkio/shlink/releases/download/v3.5.1/shlink3.5.1_php8.1_dist.zip
# unzip shlink3.5.1_php8.1_dist.zip
# mv shlink3.5.1_php8.1_dist shlink
# rm shlink3.5.1_php8.1_dist.zip
# cd shlink

phpMyAdminでshlink用データベースを作成しておく。

nginxにdataディレクトリの書き込み権限を与える。
# chown nginx.www -R data/

インストールスクリプト実行。
# vendor/bin/shlink-installer install

  • Default domain for generated short URLs: link.hoge.jp
  • multi-segment custom slugs: yes
  • How do you want short URLs to be matched?: strict
  • What kind of redirect do you want your short URLs to have? : 301

あとは全部デフォルトEnter。

GeoIP2は前にMAXMINDのアカウントを作っておいたので、新たにLicense Keyを発行して登録した。

完了後web client用API Keyをメモっておく(いつでもコマンドで確認可能)。

コマンドでteamsのURLを短縮URLに変換できるか試してみる。
# bin/cli short-url:create https://teams.microsoft.com/l/meetup-join/19%3ameeting_MTc4MDNlOWUtMjlkOC00OG...

短縮URLが生成された。
アクセスするとセキュリティ警告。

nginxのSSL設定をしてないから。


4.nginxの設定

短縮URLにアクセスしたときのnginx設定。公式サイトを参考に。
参考: Shlink — The URL shortener — Documentation

まずはcertbotでSSL証明書を取得する。
認証サーバーからアクセス可能にするnginx設定。
# cd /etc/nginx/conf.d/
# vi 01_shlink.conf

server {
    listen       80;
    server_name  link.hoge.jp;
    root    /home/httpd/shlink/public;
}

nginx再読み込み
# nginx -t
# systemctl reload nginx

certbot実行。
# certbot certonly --webroot -w /home/httpd/shlink/public -d link.hoge.jp

nginx設定変更
# less 01_shlink.conf

server {
    listen       80;
    server_name  link.hoge.jp;
    return 301 https://link.hoge.jp$request_uri;
    #root    /home/httpd/shlink/public;
}

server {
    listen       443 ssl;
    server_name  link.hoge.jp;

    root    /home/httpd/shlink/public;
    index   index.php;
    charset utf-8;

    location /.well-known/acme-challenge {
        auth_basic off;
        allow all;
    }

    location = /robots.txt  { access_log off; log_not_found off; }
    location = /favicon.ico { access_log off; log_not_found off; }

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~* \.php$ {
        include conf.d/global/fastcgi_php.conf;
    }

    include conf.d/global/ssl.conf;
    ssl_certificate         /etc/letsencrypt/live/link.hoge.jp/fullchain.pem;
    ssl_certificate_key     /etc/letsencrypt/live/link.hoge.jp/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/link.hoge.jp/chain.pem;
}

nginx再読み込み
# nginx -t
# systemctl reload nginx

さっき生成した短縮URLへブラウザでアクセスしてみる。

リダイレクトされた。ちょっと感動。


さらに設定を追加して、日本からのアクセスのみにIPアドレス制限を掛けている。
参考: nginxで国単位のIPアドレス制限


5.web clientへアクセス

shlinkはコア部分。
ウェブ管理用インターフェースが用意されている。
「https://app.shlink.io/」にアクセスしてサーバーを追加すると生成したAPI Keyで通信する。

Costom slugを入力すると任意の短縮URLに変換できる。
例えばteamsのURLを「https://link.hoge.jp/teams230217-9am」の短縮URLにできる。

メルマガやキャンペーンで使えそう。
参考: Shlink — The URL shortener — Documentation

マルチドメインにしてteamsのURLは「https://teams.hoge.jp/*****」にした方が、セキュリティ的に良いかもしれない(予測されにくい)。
…と思ったけど、日本からのアクセスのみにIPアドレス制限をかければ最悪身元を割り出せるし、入室許可しなければいいだけ。

この仕組みすごくいい。流行ると思う。
ウェブサービスの開発方法としても勉強になる。


API Keyを忘れた場合の確認方法
# cd /home/httpd/shlink/
# bin/cli api-key:list


6.shlinkコマンド

例えばMS TeamsのURLをコマンドだけで生成する場合
# cd /home/httpd/shlink/bin/
# ./cli short-url:create -c teams0217-15 https://teams.microsoft.com/l/meetup-join/19%...%7d

短縮URL一覧
# ./cli short-url:list

短縮URL削除
# ./cli short-url:delete teams0217-15

使い方はhelpを見る。
# ./cli short-url:create --help



【関連記事】