2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Dockerで自作RPMパッケージを自前のYumリポジトリで公開する環境を作った

Last updated at Posted at 2022-10-08

大学の授業で、「暇だったらCTFの問題作って」と言われました。そこで、yum info パッケージ名などと入力したらパッケージの情報とともにフラッグが表示されるという問題はどうかな?と思いましたので、それを作ってみました。

コードは下記でアップしてますので、ご確認ください。
https://github.com/fum1h1to/ctfYumRPM

構成

ctfYumRPM.drawio.png
今回は画像のように、RPMパッケージをインストールするクライアントコンテナと、Yumリポジトリを持ちRPMパッケージを提供するサーバコンテナをDockerで構築し、クライアント側でyum info -y ctfYumRPMと入力するとサーバ側からctfYumRPMをインストールできるようにします。

ちなみにパッケージの名前は、ctfYumRPMとなっています。特に理由はありません。

手順

1. RPMパッケージを作成する

RPMパッケージの作成は、後に作るクライアントコンテナ、サーバコンテナとは別の環境で作成しても問題ありません。
自分は、新たにDocker上にcentosの環境を準備しそこでRPMパッケージを作成しました。

$ docker pull centos:centos7
$ docker run -it -d -name centos7 centos:centos7
$ docker exec -it centos7 /bin/bash

なお、RPMパッケージを作成する手順については、下記を参考にさせていただきました。

自分で作ったRPMパッケージを自前のyumリポジトリで公開してみた

1. RPMパッケージの作成に必要なツールをインストール

$ yum groupinstall -y 'Development tools'
$ yum install -y rpmdevtools yum-utils

2. RPM作成用の環境を生成

$ rpmdev-setuptree

ホームディレクトリにrpmbuildというディレクトリができます。

3. SOURCESディレクトリにソースコードを入れる

ctfYumRPM.c
#include <stdio.h>

int main() {
  printf("flag{This_is_Fake}\n");
  printf("sorry:(\n");
  return 0;
}

ctfYumRPM.cなどとして~/rpmbuild/SOURCESに入れます。
これは、クライアント側で自作パッケージをインストールした後に実行できるようになるプログラムです。
今回は簡単な内容で、fakeのフラッグを出力するようにします。

4. SPECSフォルダにspecファイルを入れる

specファイルについては詳しく説明しませんが、ここに書く情報が後にyum info ctfYumRPMとした際に表示されるため、ここに本当のフラッグを書いておきます。

ctfYumRPM.spec
%define name ctfYumRPM
%define version 1.0
%define release 1

Name: %{name}
Version: %{version}	
Release: %{release}
Source0: ctfYumRPM.c
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
Summary: Where is flag???
License: flag{This_is_real_flag_Congrats}

%description
Where is flag?????????????????????????????????????

%prep
rm -rf %{buildroot}

%build
gcc /root/rpmbuild/SOURCES/ctfYumRPM.c -o /root/rpmbuild/BUILD/ctfYumRPM

%install
mkdir -p %{buildroot}/usr/bin/
install -m 755 /root/rpmbuild/BUILD/ctfYumRPM %{buildroot}/usr/bin/ctfYumRPM

%clean
rm -rf %{buildroot}

%files
/usr/bin/ctfYumRPM

ctfYumRPM.specなどとして~/rpmbuild/SPECSに入れます。

5. パッケージをビルドする

$ rpmbuild -bb ~/rpmbuild/SPECS/ctfYumRPM.spec

6. パッケージに署名する

  1. 必要なパッケージをインストール

    $ yum install -y gpg
    
  2. 鍵の生成

    $ gpg --gen-key
    

    この際、様々なことを聞かれますが、エンターで大丈夫です。
    パスワードについては、拒否するような選択をしても何度も入力しろと言われますが、そのうち諦めてくれます。

    生成した鍵を確認するときは下記コマンドです。

    $ gpg --list-key
    
  3. 鍵のexport

    $ gpg -export -a '鍵の作成時に指定した本名' > '鍵ファイル名' 
    

    自分は、

    $ gpg -export -a 'fumihito' > 'ctfYumRPM.pgp' 
    

    としました。

  4. 鍵ファイルをRPMのデータベースに登録する

    $ rpm -import '鍵ファイル名'
    
  5. ~/.rpmmacrosに内容を追加

    .rpmmacros
    %_signature gpg
    %_gpg_name <鍵の所有者名>
    

    鍵の所有者名は、鍵の作成時に指定した本名の事です。つまり自分の場合、fumihitoです。

  6. RPMファイルに署名をする

    $ rpm -addsign ~/rpmbuild/RPMS/x86_64/ctfYumRPM-1.-1.x86_64.rpm
    

    path内のx86_64については環境によっては異なる可能性があります。

    RPMファイルを検証してみましょう。

    $ rpm -checksig ~/rpmbuild/RPMS/x86_64/ctfYumRPM-1.0-1.x86_64.rpm
    /root/rpmbuild/RPMS/x86_64/ctfYumRPM-1.0-1.x86_64.rpm: rsa sha1 (md5) pgp md5 OK
    

    OKと出れば成功です。

以上で、RPMパッケージの作成は終了です。
作成したctfYumRPM-1.0-1.x86_64.rpmctfYumRPM.gpgは後に必要となります。

2. Yumのリポジトリを作成する

作成にあたって、ディレクトリ構造は下記のような形になっています。

│  docker-compose.yml
│
├─client
│  │  dockerfile
│  │
│  └─file
│          ctfYumRPM.gpg
│          fumihito.repo
│
└─server
    │  dockerfile
    │
    └─file
            ctfYumRPM-1.0-1.x86_64.rpm

サーバコンテナを用意する

Dockerでサーバを構築します。
今回RPMファイルを転送するためにHTTPを使うため、ApacheでHTTPサーバを用意します。

FROM centos:centos7

RUN yum install -y httpd
RUN yum install -y createrepo
RUN mkdir -p /var/www/html/repos/RPMS
ADD ./server/file/ctfYumRPM-1.0-1.x86_64.rpm /var/www/html/repos/RPMS
RUN createrepo /var/www/html/repos
EXPOSE 80
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

dockerfileでは、

httpdとcreaterepoをインストール

RPMを格納するディレクトリを作成

ホスト側から用意したRPMパッケージをコンテナ内に取り込む

リポジトリを作成

httpdを起動

という流れを行っています。
これで、自分の作成したRPMパッケージを提供するYumリポジトリを持ったサーバの完成です。

3. クライアント側でインストールできるようにする

クライアントコンテナを作成するわけですが、クライアント側で自作のRPMパッケージをyumでインストールするためには、以下2つを行う必要があります。

  • RPMパッケージを作成する際に作った鍵ファイルの登録
  • /etc/yum.repos.d/配下に自前のYumリポジトリの情報を追加

dockerfileはこのようになりました。

FROM centos:centos7

ADD ./client/file/ctfYumRPM.gpg /root/
ADD ./client/file/fumihito.repo /etc/yum.repos.d/
RUN rpm -import /root/ctfYumRPM.gpg

fumihito.repoは下記です。

fumihito.repo
#fumihito's yum repository
[fumihito]
name=fumihito RPM packages
baseurl=http://web:80/repos/

baseurl=http://web:80/repos/の箇所はDockerでなければ、YumリポジトリがあるサーバのIPアドレスを記入するのですが、今回はDocker上に構成するので、serviceの名前を書いています。

4. docker-compose.ymlの作成

最後にdocker-compose.ymelを作成してクライアントコンテナとサーバコンテナの起動を楽にします。

docker-compose.yml
version: "3"

services:
  web:
    tty: true
    build: 
      context: .
      dockerfile: ./server/dockerfile
    container_name: ctfYumRPM_repo
    ports: 
     - 8080:80
  
  client:
    tty: true
    build:
      context: .
      dockerfile: ./client/dockerfile
    container_name: ctfYumRPM_client

これで、docker-compose up -dとコマンドで入力することで、コンテナが起動するようになります。
そして、クライアント側に入り、ctfYumRPMをインストール出来たら成功です。

$ docker exec -it ctfYumRPM_client
$ yum install -y ctfYumRPM

確認で下記コマンドを打つと、しっかりとfakeのフラッグが出てくるはずです。

$ ctfYumRPM
flag{This_is_Fake}
sorry:(

CTFの答えとなってしまいますが、パッケージの情報を出すと本当のフラッグも出てくるはずです。

$ yum info ctfYumRPM

最後に

CTFの問題としてはすごく簡単な問題ですが、問題の環境を構築するのは大変でした。でも、Dockerってすごく便利ですね。今後も何かCTFの問題を作ってみたいです。
また、RPMやYum、Dockerについて自分の知識が浅い中で作ったので、何かおかしな点がありましたらご指摘していただきたいです。

参考文献

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?