APT proxy với Nexus trên Ubuntu
Trong môi trường enterprise, nhiều server hoặc pod không được phép truy cập Internet trực tiếp. Khi đó, một cách phổ biến là dùng Nexus làm proxy cho Ubuntu package repository để apt update và apt install đi qua nguồn nội bộ.
Nghe thì đơn giản, nhưng với các bản Ubuntu mới, nếu sửa APT source theo cách cũ quá nhanh tay, rất dễ làm hỏng cấu hình và dẫn tới các lỗi như:
503 Service UnavailableUnable to locate package unzip400 Invalid repository pathInRelease is not signed
Bài này ghi lại cách cấu hình đúng hơn, an toàn hơn, và lesson learned từ một case mình vừa xử lý thành công.
Vấn đề nằm ở đâu?
Trước đây, nhiều người quen sửa file:
/etc/apt/sources.list
Nhưng trên Ubuntu mới, hệ thống thường dùng file:
/etc/apt/sources.list.d/ubuntu.sources
Đây là format deb822, không còn là kiểu deb ... một dòng như trước. Vì vậy, nếu dùng sed để replace URL một cách mơ hồ, rất dễ tạo ra source lỗi.
Ví dụ, thay vì ra URL hợp lệ, file có thể bị biến thành chuỗi sai kiểu:
https://nexus.example.com/repository/apt-archive.ubuntu.com-proxy/APT_ARCHIVE=https://nexus.example.com/repository/apt-archive.ubuntu.com-proxy/ubuntu
Khi đó apt update sẽ báo:
400 Invalid repository path
InRelease is not signed
Và sau đó việc cài package sẽ thất bại theo dây chuyền.
Dấu hiệu nhận biết
Một số lỗi thường gặp khi APT source chưa đúng:
E: Failed to fetch http://security.ubuntu.com/... 503 Service Unavailable
hoặc:
E: Unable to locate package unzip
hoặc:
E: Failed to fetch ... 400 Invalid repository path
E: The repository '... InRelease' is not signed
Điểm cần lưu ý là Unable to locate package không nhất thiết có nghĩa package không tồn tại. Rất nhiều khi nguyên nhân thật sự là package index chưa được cập nhật đúng vì source đang sai.
Cách làm dễ sai
Một cách làm dễ thấy là replace URL bằng sed, ví dụ:
sed -i "s|http://archive.ubuntu.com/|${APT_ARCHIVE}|g" /etc/apt/sources.list.d/ubuntu.sources
sed -i "s|http://security.ubuntu.com/|${APT_SECURITY}|g" /etc/apt/sources.list.d/ubuntu.sources
Cách này nhìn có vẻ nhanh, nhưng có mấy rủi ro lớn:
dễ replace sai chuỗi
dễ chèn lặp giá trị biến
khó kiểm soát nội dung cuối cùng của file
.sourcesdễ tạo ra URL không hợp lệ mà mắt thường khó phát hiện
Với file deb822, cách an toàn hơn là backup file cũ rồi ghi đè lại nội dung chuẩn.
Cách cấu hình an toàn hơn
Bước 1: backup file hiện tại
sudo cp /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources.bak
Bước 2: ghi đè lại ubuntu.sources
sudo tee /etc/apt/sources.list.d/ubuntu.sources > /dev/null <<'EOF'
Types: deb
URIs: https://nexus.example.com/repository/apt-archive.ubuntu.com-proxy/ubuntu
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
Types: deb
URIs: https://nexus.example.com/repository/apt-security.ubuntu.com-proxy/ubuntu
Suites: noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
EOF
Trong đó:
noblelà Ubuntu 24.04nếu anh dùng Ubuntu 22.04 thì đổi thành
jammynếu dùng Ubuntu 20.04 thì đổi thành
focal
Lưu ý thêm: có môi trường Nexus yêu cầu path đầy đủ tới /ubuntu, chứ không chỉ dừng ở tên repository.
Bước 3: xóa cache APT cũ
sudo apt clean
sudo rm -rf /var/lib/apt/lists/*
Bước 4: cập nhật lại package index
sudo apt update
Nếu source đúng, apt sẽ lấy metadata từ Nexus proxy nội bộ.
Bước 5: cài package
Ví dụ:
sudo apt install -y unzip
Nếu mọi thứ ổn, package sẽ được cài bình thường.
Lệnh chạy nhanh một phát
Nếu muốn chạy gọn trong một lần:
sudo cp /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources.bak.$(date +%F-%H%M%S) && sudo tee /etc/apt/sources.list.d/ubuntu.sources > /dev/null <<'EOF'
Types: deb
URIs: https://nexus.example.com/repository/apt-archive.ubuntu.com-proxy/ubuntu
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
Types: deb
URIs: https://nexus.example.com/repository/apt-security.ubuntu.com-proxy/ubuntu
Suites: noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
EOF
sudo apt clean && sudo rm -rf /var/lib/apt/lists/* && sudo apt update && sudo apt install -y unzip
Cách kiểm tra sau khi sửa
Sau khi sửa source, nên kiểm tra lại ngay:
cat /etc/apt/sources.list.d/ubuntu.sources
apt-cache policy unzip
Nếu cấu hình đúng, apt-cache policy unzip sẽ hiển thị candidate version thay vì trống rỗng.
Troubleshooting checklist
Nếu vẫn chưa chạy được, mình sẽ kiểm tra theo thứ tự này:
1. URL Nexus có đúng path không
Ví dụ trong case của mình, URL đúng phải là:
https://nexus.example.com/repository/apt-archive.ubuntu.com-proxy/ubuntu
https://nexus.example.com/repository/apt-security.ubuntu.com-proxy/ubuntu
Thiếu /ubuntu có thể lỗi ngay.
2. Suite có đúng với version Ubuntu không
Ubuntu 24.04 →
nobleUbuntu 22.04 →
jammyUbuntu 20.04 →
focal
3. Chứng chỉ TLS của Nexus đã được trust chưa
Nếu Nexus dùng CA nội bộ, host hoặc pod cần trust CA tương ứng.
4. Nexus proxy repo đã sync metadata đầy đủ chưa
Nên kiểm tra trong Nexus xem repository đã fetch metadata và package thành công chưa.
5. Có chạy lại apt update sau khi sửa source chưa
Đây là lỗi rất hay gặp. Source sửa đúng nhưng chưa refresh package index thì vẫn sẽ báo không tìm thấy package.
Lesson learned
Case này cho mình mấy bài học khá rõ:
Trên Ubuntu mới, phải kiểm tra
ubuntu.sourcestrước khi sửa APT sourceKhông nên dùng
sedreplace mơ hồ với file.sourcesGhi đè file với nội dung chuẩn an toàn hơn nhiều
Sau khi sửa source, luôn phải
apt updateThấy
Unable to locate packagethì nên nghĩ đến source/index trước, không nên kết luận vội là package không tồn tại
Kết luận
Dùng Nexus làm APT proxy là cách rất hợp lý trong môi trường nội bộ. Nhưng trên Ubuntu mới, thứ cần quan tâm không chỉ là đổi URL repo, mà là đổi đúng file, đúng format, và đúng path.
Nếu làm cẩn thận theo hướng backup rồi ghi đè lại ubuntu.sources, việc cấu hình sẽ ổn định và dễ debug hơn rất nhiều so với replace chuỗi kiểu nhanh tay.
Sơ đồ để dễ hình dung
Anh có thể chèn sơ đồ Mermaid này vào blog hoặc đổi sang ảnh sau:
Quick reference
sudo cp /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources.bak
sudo tee /etc/apt/sources.list.d/ubuntu.sources > /dev/null <<'EOF'
Types: deb
URIs: https://nexus.example.com/repository/apt-archive.ubuntu.com-proxy/ubuntu
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
Types: deb
URIs: https://nexus.example.com/repository/apt-security.ubuntu.com-proxy/ubuntu
Suites: noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
EOF
sudo apt clean
sudo rm -rf /var/lib/apt/lists/*
sudo apt update
sudo apt install -y unzip
sudo rm -f /etc/apt/sources.list.d/ubuntu.sources.bak.*