Teleport
What is teleport?
Gravitational Teleport 是用於管理通過SSH或Kubernetes API對Linux服務器群集的訪問的網關。
它用於需要以下用途的組織,而不是傳統的OpenSSH:
Teleport 官網
Teleport 官網文檔
Teleport Installation
Teleport Github
ECMWF tsh
Panther
Teleport 架構
認證方式
Teleport Cluster 節點之間是使用 Token 和 ca 透過 Auth Server 認證信任後,產生相互之間可以信任的連結。
Teleport Node Server --> Teleport Proxy Server --> Teleport Auth Server
Role: 指定可以連至 VM 的 User
目錄結構
```
teleport
├── docker-compose.yml
└── teleport
├── config
│ └── teleport.yaml
└── data
```
docker-compose.yml
Source: Teleport docker-compose.yml example
```
version: '2'
services:
# The configure container starts, generates a config, writes it to
# /etc/teleport/teleport.yaml and then immediately exits.
configure:
image: quay.io/gravitational/teleport:5.0
container_name: teleport-configure
entrypoint: /bin/sh
hostname: localhost
command: -c "if [ ! -f /etc/teleport/teleport.yaml ]; then teleport configure > /etc/teleport/teleport.yaml; fi"
volumes:
- ./teleport/config:/etc/teleport
extra_hosts:
- "localhost:172.16.1.10"
# This container depends on the config written by the configure container above, so it
# sleeps for a second on startup to allow the configure container to run first.
teleport:
image: quay.io/gravitational/teleport:5.0
container_name: teleport
entrypoint: /bin/sh
hostname: localhost
command: -c "sleep 1 && /usr/bin/dumb-init teleport start -c /etc/teleport/teleport.yaml"
ports:
- "3023:3023"
- "3025:3025"
- "3080:3080"
volumes:
- ./teleport/config:/etc/teleport
- ./teleport/data:/var/lib/teleport
depends_on:
- configure
```
teleport/teleport/config/teleport.yaml
此檔案可先使用 docker-compose up -d && docker-compose down 創建此檔案,再做修改。
```
#
# Sample Teleport configuration file
# Creates a single proxy, auth and node server.
#
# Things to update:
# 1. ca_pin: Obtain the CA pin hash for joining more nodes by running 'tctl status'
# on the auth server once Teleport is running.
# 2. license-if-using-teleport-enterprise.pem: If you are an Enterprise customer,
# obtain this from https://dashboard.gravitational.com/web/
#
teleport:
## 顯示此 node Name
nodename: localhost
## teleport data 存放位置
data_dir: /var/lib/teleport
## 主要的 teleport Service 所使用的 token,可以自己按規範指定
auth_token: dfcb01fca61ca07e9f150baf9338e4bc24288c9f22fdcbfe
## 指定認證伺服器
auth_servers:
- 127.0.0.1:3025
log:
output: stderr
severity: INFO
ca_pin: sha256:ca-pin-hash-goes-here
## Teleport 組成 Cluster時,會透過 Nat 連線時,使用 advertise_ip 告知其他節點此 IP 為認證伺服器
# advertise_ip: 172.16.1.10
auth_service:
enabled: "yes"
listen_addr: 0.0.0.0:3025
## 指定此 Node 所要開啟的服務和tokens,如果有升級成企業版可以指定 license_file 位址
tokens:
- proxy,node:dfcb01fca61ca07e9f150baf9338e4bc24288c9f22fdcbfe
license_file: /path/to/license-if-using-teleport-enterprise.pem
## 是否開啟雙因子驗證,並使用哪種服務做驗證, second_factor: 'otp','u2f','off'
authentication:
type: local
second_factor: off
## Node 開啟時是否需要開啟 SSH service ,加上 lables 用作辨認
ssh_service:
enabled: "yes"
labels:
env: staging
commands:
- name: hostname
command: [hostname]
period: 1m0s
- name: arch
command: [uname, -p]
period: 1h0m0s
## 此項只有 Teleport Server 需要做設定
proxy_service:
enabled: "yes"
listen_addr: 0.0.0.0:3023
web_listen_addr: 0.0.0.0:3080
tunnel_listen_addr: 0.0.0.0:3024
public_addr: ["172.16.1.10:3080"]
https_keypairs: []
```
Teleport Node 安裝
在 Teleport Auth Server 使用此指令,取得快速加入命令
```
docker exec teleport tctl nodes add
---example---
teleport start \
--roles=node \
--token=6b1f875892ae8e02e1360948ff4ad89a \
--ca-pin=sha256:53977aae38c85e88d77f8e82d4b3dc7513fda8e85a62c4070f8820613f17c693 \
--auth-server=192.168.80.3:3025
注意: 使用 container 做 Teleport Auth Server,要自己將 auth-server ip 改為外部 IP
---example改---
teleport start \
--roles=node \
--token=6b1f875892ae8e02e1360948ff4ad89a \
--ca-pin=sha256:53977aae38c85e88d77f8e82d4b3dc7513fda8e85a62c4070f8820613f17c693 \
--auth-server=172.16.1.10:3025
```
Teleport Node 部屬
```
curl -O https://get.gravitational.com/teleport-v5.0.1-linux-amd64-bin.tar.gz
tar -xzf teleport-v5.0.1-linux-amd64-bin.tar.gz
cd teleport
## Tlelport data_dir 使用預設值或是指定到使用者沒有權限的目錄,請使用管理帳號安裝
sudo ./install
```
Teleport Node 環境配置
```
cat teleport/examples/systemd/README.md
cp teleport/examples/systemd/production/node/teleport.service /etc/systemd/system/teleport.service
systemctl daemon-reload
systemctl enable teleport
```
建立 /etc/teleport.yaml
```
teleport:
nodename: test1
data_dir: /var/lib/teleport
auth_token: dfcb01fca61ca07e9f150baf9338e4bc24288c9f22fdcbfe
auth_servers:
- 172.16.1.10:3025
log:
output: stderr
severity: INFO
ca_pin: sha256:53977aae38c85e88d77f8e82d4b3dc7513fda8e85a62c4070f8820613f17c693
ssh_service:
enabled: "yes"
labels:
env: staging
commands:
- name: hostname
command: [hostname]
period: 1m0s
- name: arch
command: [uname, -p]
period: 1h0m0s
## 這部份是自己加的,請依環境需求改變
- name: os
command: [cat, /etc/redhat-release]
period: 1m0s
```
啟動 Teleport Node ```systemctl start teleport```
Teleport Users Add
```
tctl users add [Teleport 帳號] [Teleport Role;並可以是節點上的 User Name]
```
新增管理用戶
```
docker exec teleport tctl users add admin admin,root
```
注意創建使用者時會出現以下內容,請即時使用內容中的 url 設定使用者密碼
```
User tung has been created but requires a password. Share this URL with the user to complete user setup, link is valid for 1h0m0s:
https://172.16.1.10:3080/web/invite/da28a1dd210b622acf7c35152a360c85
NOTE: Make sure 172.16.1.10:3080 points at a Teleport proxy which users can access.
```
新增 可使用 test 登入的用戶
```
docker exec teleport tctl users add test test
docker exec teleport tctl users add user1 test
```
* Teleport 使用者管理相關命令
```
# docker exec teleport tctl help users
usage: tctl users <command> [<args> ...]
Manage user accounts
Flags:
-d, --debug Enable verbose logging to stderr
-c, --config Path to a configuration file [/etc/teleport.yaml]
--auth-server Address of the auth server or the proxy [127.0.0.1:3025].
Can be supplied multiple times
-i, --identity Path to the identity file exported with 'tctl auth sign'
--insecure When specifying a proxy address in --auth-server, do not
verify its TLS certificate. Danger: any data you send can
be intercepted or modified by an attacker.
Commands:
users add Generate a user invitation token [Teleport DB users only]
users ls List all user accounts [Teleport DB users only]
users rm Deletes user accounts
users reset Reset user password and generate a new token [Teleport DB users only]
```
Teleport log 位置
需注意日誌的處理
```
/var/lib/teleport/log
/var/lib/teleport/log/events.log -> /var/lib/teleport/log/24d566f2-1112-463a-b484-f94d1793afe4/2021-01-09.00:00:00.log
```
額外注意事項
* Teleport Node 向 Teleport Auth Server 認證失敗
* 請刪除 Teleport Node 安狀後產生的 data_dir,ex: /var/lib/teleport
* 重新部屬 Teleport Node 後,在重新向 Teleport Auth Server 執行節點的認證
缺點
* 需要連線的機器都需要裝 Teleport
* 無法直接透過網頁介面管理使用者
* 使用 tsh client tool 需要先處理 Teleport Proxy Server 的憑證,不處理自簽憑證時,可限制 tsh 使用。
額外補充
Teleport log 送至 ElasticSearch 尚未實現
Go and structured logging with ElasticSearch
Teleport 使用自製金鑰
前置作業
```
cd /opt/teleport
mkdir ssl
cd ssl
```
創建自製 100 年 CA 公私鑰
* req:Certificate Request(PKCS #10)
* x509:輸出 x509 的 certificate ,而不要輸出 certificate request
* newkey rsa:4096:建立一個新的 4096 bits 的 RSA key
* sha256:用 SHA256 做檢查碼(Digest)
* nodes:不要幫 key 加密
* keyout:輸出 key 的檔案
* out:輸出 certificate 的檔案
* days 365:憑證的有效日期
```
openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout ca.key -out ca.crt -days 36500
```
輸入 CA crt 訊息
* Country Name (2 letter code) [XX]: 國家/地區名稱(2個字母代碼)[XX]
* State or Province Name (full name) []: 州或省名稱(全名)
* Locality Name (eg, city) [Default City]: 地區名稱(例如城市)[默認城市]
* Organization Name (eg, company) [Default Company Ltd]: 組織名稱(例如公司)[默認公司有限公司]
* Organizational Unit Name (eg, section) []: 組織單位名稱(例如,部分)[]
* Common Name (eg, your name or your server's hostname) []: 通用名稱(例如,您的名稱或服務器的主機名)[]
* Email Address []: 電子郵件地址
```
Generating a 4096 bit RSA private key
...........................................................................++
.....................................................................................++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:TW
State or Province Name (full name) []:Taiwan
Locality Name (eg, city) [Default City]:Taipei
Organization Name (eg, company) [Default Company Ltd]:TEST
Organizational Unit Name (eg, section) []:TEST CA
Common Name (eg, your name or your server's hostname) []:TEST CA
Email Address []:IT
```
產生一把 teleport 服務所需要使用的私鑰
```
openssl genrsa -out teleport.key 2048
```
建立 Template file teleport.cnf(openssl config file)
* [ req ] 表示接下來這段設定檔是給 openssl req 用的
* distinguished_name 這邊指定了我們產生 CSR 需要的資訊放在 req_dn 這一塊區域
* req_extensions 這邊指定了 CSR 要用的擴充(extension)放在 req_ext 這一塊區域
* prompt 這邊設成 no ,表示不用互動式輸入,直接拿 distinguished_name 的資料來用就可以
* [ req_dn ] 這邊指定的其實就是我們在互動式輸入裡輸入的國家、地區、domain name 等等資訊,可以參考上一篇帶過的參數
* [ req_ext ] 這邊指定的是要用的擴充相關的資訊
* 在 basicConstraints 中我們指定 CA:FALSE 表示這不是一個 CA 的 cert (非必要)
* 在 keyUsage 中我們指定了密鑰用途為數位簽名(digitalSignature)、密鑰加密(keyEncipherment);根據不同的用途這邊可以指定不同的值,可以參考 OpenSSL 文件或者直接看 RFC 3280 Section 4.2.1.3
* 在 subjectAltName 中我們指定了 SAN 設定在 alt_names 這一區;當然也可以全部用成一行寫在這邊,不過這樣看起來很累 XD
* 在 [ alt_names ] 中,我們使用 DNS.# 來指定每個 domain;當然這塊能放的其實不只有 domain ,可以參考相關文件
```
#vim teleport.cnf
--- teleport.cnf content ---
[ req ]
distinguished_name = req_dn
req_extensions = req_ext
prompt = no
[ req_dn ]
C = TW
ST = Taiwan
L = Taipei City
O = TEST
OU = TEST CA
CN = *.TEST
emailAddress = IT
[ req_ext ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = *.TEST
DNS.2 = localhost
IP.1 = 127.0.0.1
IP.2 = ::1
IP.3 = 172.16.1.10
IP.4 = 192.168.64.3
```
替 teleport.key 透過 Template Config ( teleport.cnf ) 產生 憑證申請書 ( teleport.req )
```
openssl req -new -key -sha256 -config teleport.cnf -key teleport.key -out teleport.req
```
使用 CA 公私鑰,透過憑證申請書 ( teleport.req ),替私鑰 ( teleport.cnf ) 簽名,並產生相對應的公鑰 ( teleport.crt )
* in:輸入檔案,這邊是 CSR 檔,憑證申請書 ( teleport.req )
* out:輸出檔案,這邊是產生的 certificate
* CA:CA 自己的 certificate
* CAkey:CA 自己的 key
* CAcreateserial:建立一個 CA 的序號檔(.srl),這是用來記錄 CA 簽了多少 certificate 的,只有第一次需要,也可以直接用 CAserial 指定 srl 檔
```
openssl x509 -req -days 36500 -sha256 -extfile teleport.cnf -extensions req_ext -CA ca.crt -CAkey ca.key -CAserial RootCA.srl -CAcreateserial -in teleport.req -out teleport.crt
```
* 不要使用完整的公鑰金鑰鏈,會導致服務報錯。
* 確定公鑰憑證,有依照設定檔產生
檢查憑證申請檔內容
```
openssl req -text -noout -in teleport.req
```
檢查公鑰內容
```
openssl x509 -text -noout -in teleport.crt
```
修改 teleport conf ,增加 https 位置設定
```
#vim /opt/teleport/teleport/config/teleport.yaml
--- teleport.yaml content ---
#
# Sample Teleport configuration file
# Creates a single proxy, auth and node server.
#
# Things to update:
# 1. ca_pin: Obtain the CA pin hash for joining more nodes by running 'tctl status'
# on the auth server once Teleport is running.
# 2. license-if-using-teleport-enterprise.pem: If you are an Enterprise customer,
# obtain this from https://dashboard.gravitational.com/web/
#
teleport:
nodename: localhost
data_dir: /var/lib/teleport
auth_token: dfcb01fca61ca07e9f150baf9338e4bc24288c9f22fdcbfe
auth_servers:
- 127.0.0.1:3025
log:
output: stderr
severity: INFO
ca_pin: sha256:ca-pin-hash-goes-here
# advertise_ip: 172.16.1.10
auth_service:
enabled: "yes"
listen_addr: 0.0.0.0:3025
tokens:
- proxy,node:dfcb01fca61ca07e9f150baf9338e4bc24288c9f22fdcbfe
license_file: /path/to/license-if-using-teleport-enterprise.pem
authentication:
type: local
second_factor: off
ssh_service:
enabled: "yes"
labels:
env: staging
commands:
- name: hostname
command: [hostname]
period: 1m0s
- name: arch
command: [uname, -p]
period: 1h0m0s
proxy_service:
enabled: "yes"
listen_addr: 0.0.0.0:3023
web_listen_addr: 0.0.0.0:3080
tunnel_listen_addr: 0.0.0.0:3024
public_addr: ["172.16.1.10:3080"]
https_keypairs:
- key_file: /var/lib/teleport/teleport.key
cert_file: /var/lib/teleport/teleport.crt
```
增加 teleport docker-compose.yml ssl 掛載目錄
```
#vim /opt/teleport/docker-compose.yml
--- docker-compose.yml content ---
version: '2'
services:
# The configure container starts, generates a config, writes it to
# /etc/teleport/teleport.yaml and then immediately exits.
configure:
image: quay.io/gravitational/teleport:5.0
container_name: teleport-configure
entrypoint: /bin/sh
hostname: localhost
command: -c "if [ ! -f /etc/teleport/teleport.yaml ]; then teleport configure > /etc/teleport/teleport.yaml; fi"
volumes:
- ./teleport/config:/etc/teleport
extra_hosts:
- "localhost:172.16.1.10"
# This container depends on the config written by the configure container above, so it
# sleeps for a second on startup to allow the configure container to run first.
teleport:
image: quay.io/gravitational/teleport:5.0
container_name: teleport
entrypoint: /bin/sh
hostname: localhost
command: -c "sleep 1 && /usr/bin/dumb-init teleport start -c /etc/teleport/teleport.yaml"
ports:
- "3023:3023"
- "3025:3025"
- "3080:3080"
volumes:
- ./teleport/config:/etc/teleport
- ./teleport/data:/var/lib/teleport
- ./ssl/teleport.key:/var/lib/teleport/teleport.key
- ./ssl/teleport.crt:/var/lib/teleport/teleport.crt
depends_on:
- configure
```
client 匯入自製 CA,用以信任自製 CA 所簽發的證書
```
cat ca.crt >> /etc/pki/tls/certs/ca-bundle.crt
```
使用 tsh tool 登入 teleport Server
```
cd teleport
./tsh login --user admin --proxy 172.16.1.10:3080
Enter password for Teleport user admin:
--- display conent ---
Enter password for Teleport user admin:
> Profile URL: https://172.16.1.10:3080
Logged in as: admin
Cluster: localhost
Roles: admin*
Logins: admin, root
Kubernetes: disabled
Valid until: 2021-01-11 14:56:21 +0800 CST [valid for 12h0m0s]
Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty
--- display end ---
./tsh ls
--- display conent ---
Node Name Address Labels
--------- ------------------- -------------------------------------------------------------------
localhost 127.0.0.1:3022 arch=x86_64, env=staging
hostname=localhost
test1 172.16.1.18:3022 arch=x86_64, env=staging
hostname=Office-Tung-VM-01, os=CentOS Linux release 7.6.1810 (Core)
--- display end ---
./tsh ssh test1
[root@TEST-VM ~]
#exit
--- display conent ---
the connection was closed on the remote side on 11 Jan 21 03:01 CST
--- display end ---
./tsh logout
--- display conent ---
Logged out all users from all proxies.
--- display end ---
```
沒有留言:
張貼留言