Capistrano deploy with httpproxy config
Bài đăng này đã không được cập nhật trong 5 năm
Chắc các bạn đã quen thuộc đối với việc deploy lên một server thông thường, có thể truy cập ra bên ngoài để get code, bundle. Tuy nhiên có một số dự án do tính bảo mật, server đó thuộc DNS private và không có quyền truy cập trực tiếp vào internet như vậy làm sao để có thể deploy lên một server có cấu trúc như vậy. Dưới đây chúng ta sẽ cùng tìm hiểu 1 cách để có thể làm được điều đó.
Tổng quan
+-----------+ +-------------+ +----------------+
| Git server| <---> | Jump server | --> | private Server |
+-----------+ +-------------+ +----------------+
Cấu trúc server ban đầu:
Private server
, config private IP, không có quyền access vào internet, cũng như bên ngoài access.- Deploy từ
Jump server
lênPrivate server
Jump server
được phép access vào github lấy code và truy cập được ra ngoài internet.
Vậy làm sao từ ta có thể deploy lên private server? Dưới đây sẽ là 1 cách làm mà có thể đảm bảo được tính bảo mật của private server.
- Config để
Private server
có thể ssh ngược lạiJump server
=> để private có thể ssh vàoGit server
thông quaJump server
- Config squid proxy trên
Jump server
- Cài đặt http, https proxy trên
Private server
Cài đặt Private server
ssh vào github
Thông thường khi deploy chúng ta thường deploy thông đường ssh vì key add lên 1 lần có thể dùng chung cho tất cả server mà chúng ta cần và không cần bất cứ thông tin gì khác nữa. Không giống như thông qua https
cần add 1 tài khoản và settings user password cho chúng. Vì lý do bảo mật mà Private server
không thể open ra bên ngoài => nên chúng ta sẽ cần settings để chúng có thể ssh vào github lấy code thông qua Jump server
- Đầu tiên là open port 22 từ
Private
vàojump server
- Tại
Private server
config ssh vào github vớiProxyCommand
quaJump server
# vi ~/.ssh/config
Host github.com
HostName ssh.github.com
User #{user ssh}
ProxyCommand ssh user@jump_server nc %h
Trong đó:
Host
là nickname do bạn tự chọnHostName
là remote url thực sự của server bạn muốn kết nốiUser
là tên của người dùng server bạn kết nốiProxyCommand ssh user@jump_server nc %h
lệnh chỉ định sẽ kết nối đến server bạn muốn, ở đây dùng commandnc (hay netcat)
với option%h
thay thế cho hostname của máy chủ kết nối, ngoài ra còn có những option khác như là%p
đại diện cho port kết nối hoặc%r
là user. Ở đây dùng port mặc định22
nên không cần thêm vào.jump_server
bạn có thể config host trỏ đếnIP
của jump server hoặc cũng có thể fill luôn IP vào.
Giờ chúng ta check kết nôí đến github:
ssh -T git@github.com
Hi user You've successfully authenticated, but GitHub does not provide shell access.
Như vậy đã xong bước đầu tiên, kết nối được Private server
đến github để pull code về.
Config squid proxy trên Jump server
$ sudo apt update
$ sudo apt -y install squid
$ sudo systemctl start squid
$ sudo systemctl enable squid
# Check status
$ sudo systemctl status squid
Ngoài ra cách install bạn có thể tham khảo thêm ở đây. https://www.tecmint.com/install-squid-in-ubuntu/
Config http, https proxy trên Private server
Việc config proxy chúng ta chỉ cần thêm những biến môi trường sau
export proxy_ip="ip jump sever"
export proxy_port="port squid open"
export all_proxy="http://$proxy_ip:$proxy_port"
export http_proxy="http://$proxy_ip:$proxy_port"
export https_proxy="http://$proxy_ip:$proxy_port"
ở đây ra có đăt một biến proxy_id
=> trong file config ssh chúng ta có thể sử dụng được luôn $proxy_id
để khi có thay đổi jump server id thì cũng chỉ cần thay đổi 1 chỗ là có thể sử dụng được luôn => file ssh config sẽ là:
Host github.com
HostName ssh.github.com
User #{user ssh}
ProxyCommand ssh user@$proxy_ip nc %h
Điều quan trọng ở đây là chúng ta đặt những biến môi trường proxy ở đâu để cap
có thể hiểu và chạy thông qua chúng. Chúng ta sẽ tìm hiểu một chút về capistrano với shell mode. Vì với những dạng shell mode khác nhau thì chúng sẽ load những biến môi trường ở những nơi khác nhau. Chính vì thế cần phải biết được cap đang thực thi shell ở chế độ nào.
Thông thường có 4 loại bash shell khác nhau : login
, non-login
, interactive
, và non-interactive
. Đối với những bash shell khác nhau thì sẽ load những biến môi trường khác nhau: chúng ta có thể xem sơ đồ sau để biết những biến môi trường được load ra từ đâu:
Đối với capistrano thì mặc định luôn luôn là non-login
, non-interactive
shell => như vậy chung ta có thể đặt những biến môi trường proxy tại ~/.bashrc
file. Ngoài ra thì chúng ta có thể settings để capistrano chạy trên mode interactive
bằng cách set pty
options true
.
set :pty, true
Với option này thì capistrano sẽ chạy bash shell với mode non-login
, interactive
như vậy con đường load env sẽ nhiều hơn.
Ta sẽ set trong trường hợp mặc định với mode non-login
, non-interactive
ta sẽ đặt nó vào trong ~/.bashrc
.
# vi ~/.bashrc
export proxy_ip="ip jump sever"
export proxy_port="port squid open"
export all_proxy="http://$proxy_ip:$proxy_port"
export http_proxy="http://$proxy_ip:$proxy_port"
export https_proxy="http://$proxy_ip:$proxy_port"
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
...
Một điều đặc biệt quan trọng ở đây là cần phải đặt những biến môi trường này trên đọan check
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
Vì sao lại như vậy thì dưới đây chúng ta sẽ tìm hiểu đoạn code này thực hiện gì. Chúng ta có thể thấy comment out dòng đầu cho thấy, nó đang thực thi điều gì, nếu shell chạy không phải interactively
thì sẽ không làm bất cứ action nào bên dưới mà sẽ return luôn. Cụ thể đoạn check như sau:
Nếu nó là interactive *i*)
thì nó không làm gì cả, bỏ qua cái case này đi xuống tiếp những biến dưới, còn trường hợp non-interactive*)
thì nó return khỏi script => thoát ra luôn không có chạy tiếp xuống dưới để load những env được khai báo bên dưới nữa nên không load được bất cứ env nào cả. Đối với capistrano thì nó đang để mặc định là non-interactive
nên nếu đặt dưới đoạn check này thì không bao giờ có thể load được env proxy mong muốn set.
=> Có 2 cách để có thể cho cap load được:
- Đặt env trước đoạn check
interactive
- Set
pty
true trong choCap
Như vậy là chúng ta có thể hoàn thành deploy cho một private server.
Reference https://www.cyberciti.biz/faq/linux-unix-ssh-proxycommand-passing-through-one-host-gateway-server/
All rights reserved