2021年2月21日 星期日

Teleport 跳板機

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 ---
  ```




沒有留言:

張貼留言