yumのプライベートミラーリポジトリをS3で構成する(remiの例)

# 前置き
例えばやむなくphp5.4の環境を作らねばならない案件があったとしよう

- php5.4は公式でサポートが切れているが諸々の事情で今phpアプデート対応が出来ない
- 公開されているremiなどのyumリポジトリからもいつの間にか取得できなくなるかもしれない
- 後から他パッケージが欲しくなった時、今のrpmだけ持っていても依存パッケージ不足で困るかもしれない
- コンテナイメージ化するのも手だけど、何か基礎から作り直し必要になったときどうしよう?

色々な可能性のためにyumリポジトリをまるごととりあえず持っておきたい。
というわけで公開されているremiリポジトリの現時点のミラーをS3に作って使う方法を書きます。

目的からするとバッドノウハウだよね...

# やること
今回は `remi-php54`,`remi-safe` の2つをs3 hosthingを使って構成します。
基本的にremi-safe有れば事足りますが、remi-php54が必要になるかもしれないので念の為保持してみる。
s3 Hosthingで無数のパッケージを配置するのでアクセス制限はBucket Policyで制御します。

# 手順
## yumリポジトリ構成サーバの作成

`createrepo` パッケージが必要になるため
リポジトリを構成するための作業用サーバを1台作る

yumが利用できれば良いので AmazonLinux or CentOSでOK
Vagrantなどの仮想マシンでもOK

今回は複数人での保守を考慮するのでEC2 AmazonLinux2を使います。
普段stopし、必要な時だけ起動してリポジトリ更新する運用が良いんじゃないかと思ってます。

作成手順は割愛

## 手元でミラーリポジトリの構成

- 必要パッケージインストール

  ```
  # yum install yum-utils createrepo
  ```

- remi構成のためのパッケージ導入

  ```
  $ yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
  $ yum install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
  ```

- gpg keyをインポート,手元に取得
  対象リポジトリのGPG KEYが未導入な場合はgpg keyをインポートする。
  remi-releaseを入れた場合は自身の `/etc/pki-rpm-gpg` ディレクトリに置かれるのでそれをインポートする。

  ```
  $ rpm -import file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi
  ```
  
  ※インポートするべきGPG KEYは基本的に `/etc/yum.repo.d/*.repo` に書いてあるので、remi以外でやる場合はそこから配布先を確認して適宜取得、インポート
  
- reposyncコマンドで公開リポジトリに有るrpmファイルを手元に取得する
  取得したファイル郡からリポジトリ用のメタデータを作る

  ```
  $ mkdir yum-local-repo
  $ reposync --gpgcheck -l --repoid=remi-php54 --download_path=./yum-local-repo/
  $ reposync --gpgcheck -l --repoid=remi-safe --download_path=./yum-local-repo/
  ```
  
- リポジトリ毎にcreaterepoコマンドを実行
  
  ```
  $ createrepo ./yum-local-repo/remi-php54
  $ createrepo ./yum-local-repo/remi-safe
  ```

## s3で公開
`xxxx-remi-mirror` というs3 bucketを作るとする

- s3 bucket作成
 `xxxx-remi-mirror` という名前で作成。細かいパラメータは後述。

- website hosthingの構成
  indexドキュメントは存在しないpathでOK。index.htmlと記載。

- bucket policyの設定
  s3 hosthingを構成する場合はバケットにパブリック読み取り権限が必要になる(``"Principal": "*"`` 必須)。
  制限を加える場合 Conditionエレメントを利用し条件指定で制限するのが望ましい。
  
  [ポリシーでの条件の指定 - Amazon Simple Storage Service](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/amazon-s3-policy-keys.html)

  SouceIPアドレスで制限する例
 
  ```
  {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid": "PublicReadGetObject",
              "Effect": "Allow",
              "Principal": "*",
              "Action": "s3:GetObject",
              "Resource": "arn:aws:s3:::xxx-remi-mirror/*",
              "Condition": {
                  "IpAddress": {
                      "aws:SourceIp": "xxx.xxx.xxx.xxx/32"
                  }
              }
          }
      ]
  } 
  ```

- s3 syncでファイル郡をS3にアップロード

  ```
  $ aws s3 sync ./yum-local-repo/remi-php54 s3://xxxx-remi-mirror/remi-php54
  $ aws s3 sync ./yum-local-repo/remi-safe s3://xxxx-remi-mirror/remi-safe
  ```

- s3 policy動作確認
許可したい場所からwebsite-hosthingのURLを直接叩いて確認する。

  ```
  $ curl http://xxxx-remi-mirror.s3-website-ap-northeast-1.amazonaws.com/remi-php54/repodata/repomd.xml
  $ curl http://xxxx-remi-mirror.s3-website-ap-northeast-1.amazonaws.com/remi-safe/repodata/repomd.xml
  ```

- gpg key配置
gpgcheckの目的はrpmの改ざんを防ぐこと、今回のようなプライベートなリポジトリを構成するケースでは無効化して良いかもしれない。一応公開s3に保存して利用する手順を記載する。 
  - xxxx-remi-mirrorと同じ設定で `xxxx-rpm-gpg`というバケットを構成
  - GPG-KEYをコピー

    ```
    $ aws s3 cp /etc/pki/rpm-gpg/RPM-GPG-KEY-remi s3://xxxx-rpm-gpg/RPM-GPG-KEY-remi
    ```
    
  - 動作確認

    ```
    $ rpm -import http://xxxx-rpm-gpg.s3-website-ap-northeast-1.amazonaws.com/RPM-GPG-KEY-remi
    ```

    改ざんを防ぐ目的なので、真面目にやるならgpg keyの取扱は注意が必要。
    最低限別の場所に置く方が望ましい。今回は別名bucketに配置したが別手法が良いかも。


## yum設定

プライベートリポジトリを利用する側の設定

- /etc/yum.repo.d/remi-php54.repo を編集

  baseurl, gpgkeyを修正, mirrorliestはコメントアウト, priorityは追加する

  ```
  [remi-php54]
  name=Remi's PHP 5.4 RPM repository for Enterprise Linux 7 - $basearch
  #baseurl=http://rpms.remirepo.net/enterprise/7/php54/$basearch/
  baseurl=http://xxxx-remi-mirror.s3-website-ap-northeast-1.amazonaws.com/remi-php54
  priority=1
  
  #mirrorlist=https://rpms.remirepo.net/enterprise/7/php54/httpsmirror
  #mirrorlist=http://cdn.remirepo.net/enterprise/7/php54/mirror
  enabled=0
  gpgcheck=1
  gpgkey=http://xxxx-rpm-gpg.s3-website-ap-northeast-1.amazonaws.com/RPM-GPG-KEY-remi
  
  ```
  他のリポジトリに同名パッケージが配置されている場合、他の公開リポジトリが優先されるケースがあり得るため
  priorityは上げておく事を推奨。priorityは数が小さい方が優先される。

- /etc/yum.repo.d/remi-safe.repo を編集

  baseurl,gpgkeyを修正, mirrorliestはコメントアウト, priorityは追加する

  ```
  [remi-safe]
  name=Safe Remi's RPM repository for Enterprise Linux 7 - $basearch
  #baseurl=http://rpms.remirepo.net/enterprise/7/safe/$basearch/
  #mirrorlist=https://rpms.remirepo.net/enterprise/7/safe/httpsmirror
  #mirrorlist=http://cdn.remirepo.net/enterprise/7/safe/mirror
  
  baseurl=http://xxxx-remi-mirror.s3-website-ap-northeast-1.amazonaws.com/remi-safe
  enabled=1
  gpgcheck=1
  #gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi
  gpgkey=http://xxx-rpm-gpg.s3-website-ap-northeast-1.amazonaws.com/RPM-GPG-KEY-remi
  priority=1
  ```

- 動作確認
  - remi-safe
    remi-releaseインストール時点でenabled=1に設定されているので有効化不要

    ```
    $ yum install php54 php54-php php54-php-devel php54-php-mysqlnd php54-php-mbstring php54-php-pdo php54-php-bcmath php54-php-mcrypt php54-php-pecl-memcached php54-php-pear php54-php-pecl-redis php54-php-pecl-xdebug
    ```
  - remi-php54
    remi-releaseインストール時点でenabled=0に設定されているため有効化

    ```
    $ yum install --enablerepo=remi-php54 php php-devel php-mysqlnd php-mbstring php-pdo php-bcmath php-mcrypt php-pecl-memcached php-pear php-pecl-redis php-pecl-xdebug
    ```

## 片付け
- yumリポジトリを構成したLinuxの停止

 リポジトリを更新する時以外は使わないので停止/削除してOK

# 終わり
php54使うケース書きましたが、正直サポート切れたphpなり諸々使うべきではないです。
ただ、今回のようなyumリポジトリを作っておくと再現性は高まるので、長期的に見て運用上のメリットあるはず。
プライベートなs3 hosthingなので、コストはかなり低い。

# 参考にした

- [CentOS 7でyumサーバ(yumリポジトリミラーサーバ)を構築する | 俺的備忘録 〜なんかいろいろ〜](https://orebibou.com/2015/03/centos-7%E3%81%A7yum%E3%82%B5%E3%83%BC%E3%83%90yum%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%83%9F%E3%83%A9%E3%83%BC%E3%82%B5%E3%83%BC%E3%83%90%E3%82%92%E6%A7%8B%E7%AF%89%E3%81%99%E3%82%8B/)

- [S3上にyumリポジトリを構築した話(後編) - お布団宇宙ねこ](https://ku00.hatenablog.com/entry/2015/11/14/193937)