Heesung Yang
DEB(APT) Repository 만들기
일단 아무런 설명 없이 그대로 따라서 만들어 보자. 자세한 내용은 뒤에서 설명한다.
APT Repository 생성
-
아래와 같은 폴더 구조를 만든다.
. ├── deb │ ├── dists │ │ └── stable │ │ └── main │ │ ├── binary-amd64 │ │ └── binary-arm64 │ └── pool │ └── main
~$ mkdir -p deb/dists/stable/main/binary-amd64 ~$ mkdir -p deb/dists/stable/main/binary-arm64 ~$ mkdir -p deb/pool/main
-
deb/pool/main
폴더에 deb 파일들을 복사한다.~$ cp *.deb deb/pool/main
-
Repository 생성 시 필요한 유틸리티를 설치한다.
~$ sudo apt install apt-utils dpkg-dev
-
Packages 파일을 생성한다.
~$ cd deb/ ~$ dpkg-scanpackages -m --arch amd64 pool/ > dists/stable/main/binary-amd64/Packages ~$ dpkg-scanpackages -m --arch amd64 pool/ | gzip -9 > dists/stable/main/binary-amd64/Packages.gz ~$ dpkg-scanpackages -m --arch arm64 pool/ > dists/stable/main/binary-arm64/Packages ~$ dpkg-scanpackages -m --arch arm64 pool/ | gzip -9 > dists/stable/main/binary-arm64/Packages.gz
-
Release 파일을 생성한다.
~$ cd dists/stable/ ~$ cat > Release << EOF Origin: My Home Label: My Home Suite: stable Version: 1.0 Architectures: amd64 arm64 Components: main Description: my software repository EOF ~$ apt-ftparchive release . >> Release
-
GPG Key Pair를 생성한다.
- GPG 공개키/개인키 쌍 만들기 문서를 참고하자.
-
생성한 GPG Key 를 이용하여 Release 파일에 서명한다.
# 5번 과정에서 Key Pair 생성 시 입력한 Real name 값이 mykey 인 경우 ~$ cd deb/dists/stable ~$ gpg --clearsign -o InRelease --default-key mykey Release ~$ gpg -abs -o Release.gpg --default-key mykey Release
-
5번에서 생성한 GPG Key 의 공개키를 추출한 후 deb 저장소 최상단에 복사한다.
# 5번 과정에서 Key Pair 생성 시 입력한 Real name 값이 mykey 인 경우 ~$ gpg --armor --export mykey > pub.key ~$ mv pub.key deb/
-
Web 서버를 실행한다. (여기서는 간단하게 python3를 이용)
~$ cd deb/ ~$ python3 -m http.server Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
APT Repository 추가
위에서 생성한 Repository를 서버에 추가하는 과정이다. Repository 서버의 IP 주소가 1.1.1.1 이라고 가정하였다.
-
public key 등록
~$ curl http://1.1.1.1:8000/pub.key | sudo apt-key add -
-
sources.list 추가
- 만약 arm64 기반이라면 [arch=arm64] 로 변경
~$ sudo cat > /etc/apt/sources.list.d/my.list <<EOF deb [arch=amd64] https://1.1.1.1:8000 stable main EOF
-
apt 캐쉬 업데이트
~$ sudo apt update
개념
sources.list format
/etc/apt/sources.list 파일을 열어보면 다음과 같이 저장소가 정의되어 있다.
deb http://archive.ubuntu.com/ubuntu focal main restricted
위 파일의 포맷은 man sources.list
명령어로 확인할 수 있는데, 아래와 같이 설명되어 있다.
deb [ option1=value1 option2=value2 ] uri suite [component1] [component2] [...]
deb-src [ option1=value1 option2=value2 ] uri suite [component1] [component2] [...]
Types
첫 번째 항목으로, deb / deb-src 값 중 하나를 쓸 수 있다.
- deb : binary package 저장소
- deb-src : source code package 저장소
Types Options
두 번째 항목으로, 생략 시 default option이 적용된다. 각 옵션은 공백으로 구분한다. 아래와 같이 []
안에 옵션 값을 설정한다.
deb [arch=amd64 trusted=yes] https://download.docker.com/linux/ubuntu focal stable
자주 접하는 옵션만 설명한다. 모든 옵션은 man sources.list 에서 확인하자.
- arch
- string
- 어떤 architecture에 대한 저장소인지 설정한다. 생략 시 모든 architecture에 대한 저장소로 설정된다.
- allow-insecure
- boolean (yes/no)
- 저장소에 Release 파일이 없거나 서명되지 않은 Release 파일이 있는 경우, apt update 명령 실행 시 데이터를 다운로드 받지 않는다. 그러나 해당 옵션 적용 시 warning 메시지만 띄우고 데이터를 다운로드 한다.
- trusted
- boolean (yes/no)
- 저장소에 Release 파일이 없거나 서명되지 않은 Release 파일이 있는 경우에도 warning 메시지 없이 데이터를 다운로드 한다.
URI
세 번째 항목으로, 저장소의 root url을 지정한다. 사용가능한 URI 타입은 다음과 같다.
-
http
-
https
-
mirror, mirror+scheme
-
file
-
디스크의 특정 경로를 저장소로 사용할 경우 사용한다. 아래와 같이 설정한다.
file:/home/apt/debian
-
-
cdrom
-
ftp
-
copy
-
rsh, ssh
Suites, Component
Suites가 네 번째, 그 이후 Component는 몇 개든 쓸 수 있다.
Suties 값은 보통 배포판의 codename
을 사용하거나 stable
과 같은 값을 사용한다.
실제로는 저장소 root 의 하위 폴더 이름을 의미한다.
아래 예를 보자.
deb http://archive.ubuntu.com/ubuntu focal main restricted
위 예에서 Suites는 focal
, Component는 main
과 restricted
이다. 실제 서버의 폴더 구조는 아래와 같다.
.
└── ubuntu << URI Root
└── dists
└── focal << Suites
├── main << Component1
└── restricted << Component2
Suites과 Component는 모든 패키지 파일을 한 폴더에서 관리하지 않고 폴더 별로 나눠서 관리하기 위한 방법이라 생각하자.
Meta data
Release, InRelease
apt 명령어로 패키지를 다운로드할 때, 가장 먼저 이 파일을 다운로드 받는다. 이 파일은 아래 위치(Suites 하위)에 존재해야 한다.
deb http://archive.ubuntu.com/ubuntu focal main restricted
.
└── ubuntu << URI Root
└── dists
└── focal << Suites
├── InRelease
├── Release
├── main << Component1
└── restricted << Component2
Release
파일은 저장소의 파일들의 hash 정보를 기록한 텍스트 파일이다. (다운로드한 파일의 무결성 체크를 위해 사용)
Release
파일은 Release.gpg
파일 또한 함께 제공되어야 하는데, Release
파일에 대한 서명 정보이다.
InRelease
파일은 Relase
+ Release.gpg
라고 생각하면 된다. (두 개의 파일을 하나로 합침)
Packages
Packages 파일은 실제 deb 파일들에 대한 Meta 정보가 포함되어 있는 텍스트 파일이다. apt 명령어 실행 시 이 파일을 읽어서 패키지 정보를 알아내는 것으로 추정한다. Packages 파일은 아래 위치한다.
.
├── dists
│ └── stable
│ ├── InRelease
│ ├── main
│ │ ├── binary-amd64
│ │ │ ├── Packages <<---
│ │ │ └── Packages.gz <<---
│ │ └── binary-arm64
│ │ ├── Packages <<---
│ │ └── Packages.gz <<---
│ ├── Release
│ └── Release.gpg
├── pool
└── main
Reference
- https://wiki.debian.org/DebianRepository/Format
- https://help.ubuntu.com/community/CreateAuthenticatedRepository
- https://wiki.debian.org/SecureApt
- https://earthly.dev/blog/creating-and-hosting-your-own-deb-packages-and-apt-repo/
- https://bgstack15.wordpress.com/2016/06/22/building-an-apt-repository-on-centos/
Previous post
GPG 공개키/개인키 쌍 만들기Next post
AWS CLI [CloudFront] - Cache 삭제 방법