使用Vault

以前曾經(jīng)介紹過關(guān)于KMS的用法商佛,其中,提到了它的優(yōu)點(diǎn)和用處姆打,我們使用的場景有如下幾點(diǎn):

  1. 我們產(chǎn)品的環(huán)境的所有的配置都保存在git上(Config As Code?)良姆,所以相關(guān)的密碼、private key等需要加密
  2. 對AWS上應(yīng)用/服務(wù)涉及的敏感數(shù)據(jù)進(jìn)行加密
  3. AWS上傳輸?shù)臄?shù)據(jù)進(jìn)行加密幔戏,比如SQS

如果脫離AWS玛追,選擇好像還真是不太多,Harshicorp的Vault是我僅知道的一個(gè)闲延,RatticDB算半個(gè)吧痊剖。

什么是Vault


Vault提供了對token,密碼垒玲,證書陆馁,API key等的安全存儲(chǔ)(key/value)和控制,合愈。它能處理key的續(xù)租叮贩、撤銷、審計(jì)等功能想暗。通過API訪問可以獲取到加密保存的密碼妇汗、ssh key、X.509的certs等说莫。它的特性包括:

  1. 加密存儲(chǔ). 沒有做到KMS對存儲(chǔ)的HMS(硬件加密)杨箭,但是它傳輸后端提供與KMS類似的功能,允許存儲(chǔ)加密密鑰并執(zhí)行加密操作储狭。 它可以存儲(chǔ)已存在的credentials互婿,也可以為你的基礎(chǔ)設(shè)施動(dòng)態(tài)生成新的credential來限制第三方的訪問,這些credentials到期會(huì)被撤銷辽狈,也可以續(xù)租慈参。同時(shí)還有訪問控制策略來進(jìn)行訪問的權(quán)限管理。
  2. rotate key刮萌。如果把Vault當(dāng)做加密服務(wù)來使用的話驮配,可以設(shè)置rotate的時(shí)間來生成一個(gè)新的key。
  3. 審計(jì)的日志。所有對API的調(diào)用都會(huì)記錄在一個(gè)審計(jì)日志上壮锻,

因?yàn)槭褂肰ault的目的是為了

  1. 持續(xù)集成服務(wù)器上運(yùn)行測試或者部署需要的密碼琐旁、API key、以及private key等需要加密
  2. 服務(wù)部署是將加密后的應(yīng)用需要的配置解密
    同時(shí)我不希望在服務(wù)器上安裝vault的命令行工具猜绣,所以在下面的使用中我都用Restful API的方式灰殴。

啟動(dòng)Vault服務(wù)


Vault存儲(chǔ)[backend(https://www.vaultproject.io/docs/secrets/index.html)]可以是

  1. 內(nèi)存(開發(fā)模式)
  2. 磁盤/數(shù)據(jù)庫
  3. Consoul
  4. AWS
  5. ...

我在用Docker啟動(dòng)Vault服務(wù)的時(shí)候使用的Production模式,為了簡單使用了磁盤作為存儲(chǔ)掰邢,但是為了persist牺陶,所以將valut的文件存在了docker volume上面。
docker-compose文件如下:

version: "2"
services:
  vault:
    image: vault:0.6.4
    volumes:
        - vault-volume:/vault/file
    environment: 
        VAULT_LOCAL_CONFIG:  '{"backend": {"file": {"path": "/vault/file"}}, "default_lease_ttl": "168h", "max_lease_ttl": "720h", "listener": {"tcp": {"address": "0.0.0.0:8200", "tls_disable": "1"}}, "disable_mlock": true}'
    command: "server"
    cap_add: 
      - IPC_LOCK  #--cap-add: Add Linux capabilities,  in order for Vault to lock memory
    ports:
        - 8200:8200
volumes:
   vault-volume:
      external: true    

創(chuàng)建volume辣之,啟動(dòng)vault服務(wù)器掰伸,配置通過環(huán)境變量VAULT_LOCAL_CONFIG傳入。

docker volume create --name vault-volume
docker-compose up -d

從本地的8200端口應(yīng)該就可以訪問到了:

 telnet 0 8200
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
^]

初始化


下面的API請求可以對Vault進(jìn)行初始化召烂,兩個(gè)參數(shù)的意思將master key分成幾份以及還原碱工,這里就用1吧。

curl -X PUT -d "{\"secret_shares\":1, \"secret_threshold\":1}"  http://127.0.0.1:8200/v1/sys/init | jq

返回結(jié)果:

{
  "keys": [
    "36d8ae19eb3e9d48965011e49af99865ca2bc6c78f4e900b7e14482d048d5ea2"
  ],
  "keys_base64": [
    "NtiuGes+nUiWUBHkmvmYZcorxsePTpALfhRILQSNXqI="
  ],
  "root_token": "e4347e60-0e72-fa8f-05e8-94c7388bb12c"
}

第一個(gè)是master key的public key奏夫,第二個(gè)是unseal key,最后一個(gè)是root token怕篷。unseal vault之后才能驗(yàn)證進(jìn)行具體的操作。

curl -X PUT -d '{"key": "NtiuGes+nUiWUBHkmvmYZcorxsePTpALfhRILQSNXqI="}'  http://127.0.0.1:8200/v1/sys/unseal | jq

結(jié)果:

{
  "sealed": false,
  "t": 1,
  "n": 1,
  "progress": 0,
  "version": "0.6.4",
  "cluster_name": "vault-cluster-603ef85a",
  "cluster_id": "ac454859-dc57-ee1d-38c1-71a0226a8cf3"
}

創(chuàng)建新token

為了安全起見酗昼,我們可以用root token創(chuàng)建出有限權(quán)限的新token廊谓,來繼續(xù)后面的操作。假設(shè)這個(gè)token可以讀寫的路徑為secret/*麻削。在這個(gè)之前我們先創(chuàng)建訪問這個(gè)路徑的policy:

 curl -v  -X POST  -H "X-Vault-Token:e4347e60-0e72-fa8f-05e8-94c7388bb12c" -d '{"rules":"path \"secret/*\" {\n  policy = \"write\"\n}"}'   http://127.0.0.1:8200/v1/sys/policy/admin-policy

 curl -X GET  -H "X-Vault-Token:e4347e60-0e72-fa8f-05e8-94c7388bb12c"  http://127.0.0.1:8200/v1/sys/policy/admin-policy   | jq

{
  "rules": "path \"secret/*\" {\n  policy = \"write\"\n}",
  "name": "admin-policy",
  "request_id": "c7e5a70d-bca8-54b9-eb1d-793f3b027e1f",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": {
    "name": "admin-policy",
    "rules": "path \"secret/*\" {\n  policy = \"write\"\n}"
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null
} 

對應(yīng)的創(chuàng)建user-policy:

curl -v -X POST  -H "X-Vault-Token:e4347e60-0e72-fa8f-05e8-94c7388bb12c" -d '{"rules":"path \"secret/*\" {\n  policy = \"read\"\n}"}'   http://127.0.0.1:8200/v1/sys/policy/user-policy

curl -X GET  -H "X-Vault-Token:e4347e60-0e72-fa8f-05e8-94c7388bb12c"  http://127.0.0.1:8200/v1/sys/policy/user-policy | jq

{
  "name": "user-policy",
  "rules": "path \"secret/*\" {\n  policy = \"read\"\n}",
  "request_id": "104fd2f3-f0ae-86f6-c1f7-ed3df01be962",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": {
    "name": "user-policy",
    "rules": "path \"secret/*\" {\n  policy = \"read\"\n}"
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null
}

然后我們分別創(chuàng)建兩個(gè)token蒸痹,admin token和 user token:

curl -X POST -d '{"policies": ["admin-policy"]}' -H "X-Vault-Token:e4347e60-0e72-fa8f-05e8-94c7388bb12c"  http://127.0.0.1:8200/v1/auth/token/create | jq

{
  "request_id": "a58efd8f-4585-d736-4d69-e8ee1d29f19a",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": null,
  "wrap_info": null,
  "warnings": null,
  "auth": {
    "client_token": "a1ab3379-665f-15bf-0035-32e059e5d055",
    "accessor": "a1e6d92c-9788-a980-04a6-bfa45b0b7c26",
    "policies": [
      "admin-policy",
      "default"
    ],
    "metadata": null,
    "lease_duration": 604800,
    "renewable": true
  }
}
 curl -X POST -d '{"policies": ["user-policy"]}' -H "X-Vault-Token:e4347e60-0e72-fa8f-05e8-94c7388bb12c"  http://127.0.0.1:8200/v1/auth/token/create | jq

{
  "request_id": "c32dc4a6-e432-48db-c59d-5a32c5d780cb",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": null,
  "wrap_info": null,
  "warnings": null,
  "auth": {
    "client_token": "5d9e8e7f-e133-4cfa-6f67-880f2799235b",
    "accessor": "ed1c10ec-ca1b-7d1f-3a0a-ca4763ea3cec",
    "policies": [
      "default",
      "user-policy"
    ],
    "metadata": null,
    "lease_duration": 604800,
    "renewable": true
  }
}

這樣就有了對于secrets/*路徑下進(jìn)行讀寫的兩個(gè) token,可以嘗試去admin的token去添加新的鍵值對:

export ADMIN_TOKEN="a1ab3379-665f-15bf-0035-32e059e5d055"
curl -X POST -H "X-Vault-Token:$ADMIN_TOKEN" -d '{"token":"c192d0211cb81fbfeee53fb16e2a7465"}' http://127.0.0.1:8200/v1/secret/api/search

export USER_TOKEN="5d9e8e7f-e133-4cfa-6f67-880f2799235b"
 curl -X GET -H "X-Vault-Token:$USER_TOKEN" http://127.0.0.1:8200/v1/secret/api/search | jq

{
  "request_id": "dd2fcbae-b74f-6fc8-b895-a2c78667b1f0",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 604800,
  "data": {
    "token": "c192d0211cb81fbfeee53fb16e2a7465"
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null
}

 curl -X POST -H "X-Vault-Token:$USER_TOKEN" -d '{"token":"286755fad04869ca523320acce0dc6a4"}' http://127.0.0.1:8200/v1/secret/api/search | jq

{
  "errors": [
    "permission denied"
  ]
}

這樣就有了基本的權(quán)限管理呛哟。假設(shè)vault服務(wù)器和應(yīng)用服務(wù)器或者CI的服務(wù)器部署在同一私有網(wǎng)絡(luò)中叠荠,應(yīng)用服務(wù)器和CI slave是不可以ssh的,那么通過應(yīng)用服務(wù)器或者CI在啟動(dòng)的時(shí)候通過HTTP請求扫责,利用讀權(quán)限的user-token就可以拿到API-TOKEN榛鼎,同時(shí)沒有暴露給外部。

使用AppRoles的驗(yàn)證方式


AWS的EC2 instance上可以綁定instanceProfile, instanceProfile對應(yīng)的是IAM的role鳖孤,這個(gè)role可以設(shè)置對AWS資源的訪問權(quán)限者娱,比如對S3某個(gè)bucket的寫權(quán)限,或者對Dynamodb的寫權(quán)限等苏揣。Vault提供的AppRoles的功能比instanceProfile要差很多黄鳍,不過確實(shí)可以將機(jī)器和一定權(quán)限的Role綁定起來,控制訪問的范圍平匈。

允許使用approle的驗(yàn)證方式同時(shí)創(chuàng)建一個(gè)給CI slave使用的role:

export VAULT_TOKEN="e4347e60-0e72-fa8f-05e8-94c7388bb12c"
curl -X POST -H "X-Vault-Token:$VAULT_TOKEN" -d '{"type":"approle"}' http://127.0.0.1:8200/v1/sys/auth/approle   

curl -X POST -H "X-Vault-Token:$VAULT_TOKEN" -d '{"policies":"user-policy"}' http://127.0.0.1:8200/v1/auth/approle/role/deploy-role    #這里請求的參數(shù)可以指定請求來源的CIDR block '{"policies":"user-policy", "bound_cidr_list":"172.20.32.0/28"}'框沟,只有在這個(gè)ip range里面的服務(wù)器才能使用這個(gè)role從vault拿到指定數(shù)據(jù) 

下面的API請求可以拿到role-id藏古,以及根據(jù)role-id生成secret-id,利用它們可以登錄獲得從vault讀取數(shù)據(jù)的權(quán)限:

curl -X GET -H "X-Vault-Token:$VAULT_TOKEN"          http://127.0.0.1:8200/v1/auth/approle/role/deploy-role/role-id | jq .

{
  "request_id": "553d9fa9-50a2-274e-77f9-675c200d8cd1",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": {
    "role_id": "9d830303-2e06-b432-9023-677eb886041c"
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null
}

  curl -X POST -H "X-Vault-Token:$VAULT_TOKEN" http://127.0.0.1:8200/v1/auth/approle/role/deploy-role/secret-id | jq .

{
  "request_id": "ab5edb82-d1a9-b751-47c6-e2e0fe7ca333",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": {
    "secret_id": "6788593e-2c9b-0bae-0b0d-4b2c8d84e81d",
    "secret_id_accessor": "f88c33fd-431d-35aa-6295-6d7ecd6b34d1"
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null
}

使用secret_idrole_id聯(lián)合登錄忍燥,拿到新的token:

 curl -X POST  -d '{"role_id":"9d830303-2e06-b432-9023-677eb886041c","secret_id":"6788593e-2c9b-0bae-0b0d-4b2c8d84e81d"}' http://127.0.0.1:8200/v1/auth/approle/login | jq '{client_token: .auth.client_token}'

{
  "client_token": "e0fe3cfb-1323-4ec6-9490-d6ac06dc3c69"
}

然后利用client_token去讀取前面寫入到vault中的search api token:

 ~> curl -X GET -H "X-Vault-Token:e0fe3cfb-1323-4ec6-9490-d6ac06dc3c69"  http://127.0.0.1:8200/v1/secret/api/search | jq '{"api-token": .data.token}'
{
  "api-token": "c192d0211cb81fbfeee53fb16e2a7465"
}

秘鑰管理


AWS的EC2 instance的服務(wù)器校翔,在啟動(dòng)時(shí),可以綁定一對ssh keypair灾前,以方便用戶使用缺省的ec2-userssh到服務(wù)器上。從最佳實(shí)踐的角度來說孟辑,應(yīng)該把服務(wù)器當(dāng)做immutable的設(shè)施哎甲,不允許ssh。但是現(xiàn)實(shí)比較嘲諷饲嗽,這樣的需求仍然存在炭玫,那么我們可以換種方式,盡量做好ssh key的管理貌虾。
比如吞加,對于每個(gè)新啟動(dòng)的服務(wù)器,動(dòng)態(tài)的生成一對ssh keypair尽狠,只應(yīng)用在這臺(tái)服務(wù)器上衔憨,服務(wù)器銷毀后,吊銷key pair袄膏。
Vault提供了ssh keypair的管理功能践图,利用這個(gè)功能我們可以對key的生命周期的管理。它支持兩種方式:

  1. One-Time-Password (OTP) Type
  2. Dynamic Key Type
    個(gè)人傾向于使用動(dòng)態(tài)key沉馆,但是官方的文檔推薦OTP類型码党,原因是無法對動(dòng)態(tài)的key的使用進(jìn)行audit,還有一個(gè)就是生成動(dòng)態(tài)的key會(huì)消耗資源導(dǎo)致vault服務(wù)的停頓(好失望:()斥黑。Anyway揖盘,不管它。

要讓vault發(fā)放keypair, 需要先注冊一個(gè)private key锌奴,這個(gè)key必須有服務(wù)器的管理權(quán)限.之后兽狭,你需要?jiǎng)?chuàng)建一個(gè)role,包括一些限定條件缨叫,如admin用戶的名字椭符,缺省用戶,目標(biāo)服務(wù)器的IP地址應(yīng)該匹配的CIDR地址耻姥,具體過程如下:

export VAULT_ADDR=http://127.0.0.1:8200
export VAULT_TOKEN=e4347e60-0e72-fa8f-05e8-94c7388bb12c

vault write ssh/keys/deploy-role key=@shared_deploy_key.pem  

vault write ssh/roles/deploy-role \
    key_type=dynamic \
    key=shared_deploy_key \
    admin_user=root \
    default_user=ec2-user \
    cidr_list=172.23.0.0/16   #目標(biāo)服務(wù)器的IP地址需要在CIDR的范圍內(nèi)

vault write ssh/creds/deploy-role ip=172.23.0.6

整個(gè)的過程大概是這樣销钝,vault利用注冊的private key登陸到目標(biāo)服務(wù)器上,然后將新生成的key pair中的public key寫入到目標(biāo)服務(wù)器的authorized_keys文件中琐簇。在你想登陸到服務(wù)器上的時(shí)候蒸健,用對應(yīng)的client token驗(yàn)證座享,獲取private key,ssh登陸似忧。key有過期時(shí)間渣叛,過期之后就被revoke了。

PKI 管理


我覺得全站https困難之一就在于PKI的管理盯捌,今年出現(xiàn)過幾次certficate過期導(dǎo)致的產(chǎn)品環(huán)境的問題淳衙,還好及時(shí)的切換到了AWS Certificate Manager,免費(fèi)而且到期自動(dòng)續(xù)租饺著,基本上不用擔(dān)心管理的問題了箫攀。而我們原有的內(nèi)部PKI管理要稍微麻煩些,需要用自己業(yè)務(wù)線的LOB Intermediate CA去簽發(fā)新的certs幼衰,運(yùn)行一些自動(dòng)化的腳本靴跛,還得從RatticDB里面找到對應(yīng)的private key。
但是如果基礎(chǔ)設(shè)施不是基于AWS渡嚣,好像就沒有很合適的工具了梢睛,只能自己維護(hù)PKI,Vault也提供了PKI的管理识椰,可以在這方面提供幫助绝葡。考慮環(huán)境的一致性裤唠,開發(fā)挤牛、測試以及staging也需要certificate,我覺得這個(gè)功能是有意義的种蘸。

vault mount -path=example -description="example Root CA" -max-lease-ttl=87600h pki

vault write example/root/generate/internal common_name=example.com ttl=87600h key_bits=4096
Key             Value
---             -----
certificate     -----BEGIN CERTIFICATE-----
MIIDFDCCAfygAwIBAgIUCugj4117yjDXigWcflp7nA6lAp0wDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYxMjIzMDU0MjQ3WhcNMjYx
MjIxMDU0MzE3WjAWMRQwEgYDVQQDEwtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcN
....
-----END CERTIFICATE-----
serial_number   0a:e8:23:e3:5d:7b:ca:30:d7:8a:05:9c:7e:5a:7b:9c:0e:a5:02:9d

Vault會(huì)安全的保存Root CA 的private key墓赴。 可以通過http請求拿到ca的pem文件。

curl -s http://127.0.0.1:8200/v1/example/ca/pem | openssl x509 -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            0a:e8:23:e3:5d:7b:ca:30:d7:8a:05:9c:7e:5a:7b:9c:0e:a5:02:9d
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=example.com
        Validity
            Not Before: Dec 23 05:42:47 2016 GMT
            Not After : Dec 21 05:43:17 2026 GMT
        Subject: CN=example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
....

需要給Vault配置訪問CA和CRL(certificate revocation list)的地址航瞭。

vault write example/config/urls issuing_certificates="http://127.0.0.1:8200/v1/example"
Success! Data written to: example/config/urls

創(chuàng)建intermediate CA.

vault mount -path=example_lob  -description="Example LOB Intermediate CA" -max-lease-ttl=26280h pki
Successfully mounted 'pki' at 'example_lob'!

vault write example_lob/intermediate/generate/internal  common_name="Example LOB Intermediate CA" ttl=26280h key_bits=4096 exclude_cn_from_sans=true

Key Value
--- -----
csr -----BEGIN CERTIFICATE REQUEST-----
...
-----END CERTIFICATE REQUEST-----

把這個(gè)csr內(nèi)容存在example_lob.csr文件中诫硕,請求root ca簽發(fā)這個(gè)intermediate ca。

vault write example/root/sign-intermediate csr=@example_lob.csr common_name="Example LOB Intermediate CA" ttl=8760h

Key             Value
---             -----
certificate     -----BEGIN CERTIFICATE-----
MIIElTCCA32gAwIBAgIUH1UgMxdv8fGTMAfTFc86JHVnfB4wDQYJKoZIhvcNAQEL
....
-----END CERTIFICATE-----
expiration      1514009491
issuing_ca      -----BEGIN CERTIFICATE-----
MIIDFDCCAfygAwIBAgIUCugj4117yjDXigWcflp7nA6lAp0wDQYJKoZIhvcNAQEL
....
-----END CERTIFICATE-----
serial_number   1f:55:20:33:17:6f:f1:f1:93:30:07:d3:15:cf:3a:24:75:67:7c:1e

得到Root CA的簽發(fā)過的intermediate CA certs后刊侯,保存為文件章办,導(dǎo)入两入。最后就是要設(shè)置CA/CRL便瑟,和上面相同裳瘪。

vault write example_lob/intermediate/set-signed certificate=@example_lob.crt
Success! Data written to: example_lob/intermediate/set-signed

curl -s http://localhost:8200/v1/example_lob/ca/pem | openssl x509 -text | head -15
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            23:0e:28:69:08:d1:5e:c9:10:8d:61:fe:46:4b:c6:09:ef:44:73:db
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=example.com
        Validity
            Not Before: Dec 23 06:23:55 2016 GMT
            Not After : Dec 23 06:24:25 2017 GMT
        Subject: CN=Example LOB Intermediate CA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (4096 bit)
                Modulus (4096 bit):

vault write example_lob/config/urls issuing_certificates="http://127.0.0.1:8200/v1/example_lob/ca" 
Success! Data written to: example_lob/config/urls

在開始給server簽發(fā)certs前阱佛,需要?jiǎng)?chuàng)建role,之后就可以簽發(fā)了目木。

vault write example_lob/roles/web_server key_bits=2048 max_ttl=8760h allow_any_name=true
Success! Data written to: example_lob/roles/web_server

vault write example_lob/issue/web_server common_name="auth.lob.example.com" ip_sans="172.23.0.2" ttl=720h format=pem


Key                 Value
---                 -----
lease_id            example_lob/issue/web_server/a5c7ba76-34b5-b2a8-5262-3cd3fbc1630e
lease_duration      719h59m59s
lease_renewable     false
ca_chain            [-----BEGIN CERTIFICATE-----
....
-----END CERTIFICATE-----]
certificate         -----BEGIN CERTIFICATE-----
....
-----END CERTIFICATE-----
issuing_ca          -----BEGIN CERTIFICATE-----
....
-----END CERTIFICATE-----
private_key         -----BEGIN RSA PRIVATE KEY-----
....
-----END RSA PRIVATE KEY-----
private_key_type    rsa
serial_number       5a:11:20:aa:35:ad:3a:dd:22:a8:8c:4b:26:04:a8:e5:ce:fb:96:74

拿到private key和crt就可以放在服務(wù)器上測試了芭挽,感覺用這個(gè)grunt-connect-proxy測試起來可能會(huì)快點(diǎn)暗挑。

其他


Vault還有一個(gè)我覺得很好的特性是可以將LDAP作為auth的backend辜羊,感覺維護(hù)的壓力又小了很多:) 剩下的特性大家可以自己嘗試踏兜,我們也正在考慮把替換RatticDB保存一些private key之類的credential词顾,下次的security meetup上面我可以展示下spike的成果……。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末碱妆,一起剝皮案震驚了整個(gè)濱河市肉盹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌疹尾,老刑警劉巖上忍,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異纳本,居然都是意外死亡睡雇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門饮醇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人秕豫,你說我怎么就攤上這事朴艰。” “怎么了混移?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵祠墅,是天一觀的道長。 經(jīng)常有香客問我歌径,道長毁嗦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任回铛,我火速辦了婚禮狗准,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘茵肃。我一直安慰自己腔长,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布验残。 她就那樣靜靜地躺著捞附,像睡著了一般。 火紅的嫁衣襯著肌膚如雪您没。 梳的紋絲不亂的頭發(fā)上鸟召,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音氨鹏,去河邊找鬼欧募。 笑死,一個(gè)胖子當(dāng)著我的面吹牛喻犁,可吹牛的內(nèi)容都是我干的槽片。 我是一名探鬼主播何缓,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼还栓!你這毒婦竟也來了碌廓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬榮一對情侶失蹤剩盒,失蹤者是張志新(化名)和其女友劉穎谷婆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體辽聊,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡纪挎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了跟匆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片异袄。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖玛臂,靈堂內(nèi)的尸體忽然破棺而出烤蜕,到底是詐尸還是另有隱情,我是刑警寧澤迹冤,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布讽营,位于F島的核電站,受9級(jí)特大地震影響泡徙,放射性物質(zhì)發(fā)生泄漏橱鹏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一堪藐、第九天 我趴在偏房一處隱蔽的房頂上張望莉兰。 院中可真熱鬧,春花似錦礁竞、人聲如沸贮勃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽寂嘉。三九已至,卻和暖如春枫绅,著一層夾襖步出監(jiān)牢的瞬間泉孩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來泰國打工并淋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留寓搬,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓县耽,卻偏偏與公主長得像句喷,于是被迫代替她去往敵國和親镣典。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理唾琼,服務(wù)發(fā)現(xiàn)兄春,斷路器,智...
    卡卡羅2017閱讀 134,654評(píng)論 18 139
  • Vault是用來安全的獲取秘密信息的工具锡溯,它可以保存密碼赶舆、API密鑰、證書等信息祭饭。Vault提供了一個(gè)統(tǒng)一的接口來...
    陌辭寒閱讀 7,033評(píng)論 1 3
  • CA和證書安全協(xié)議(SSL/TLS)OpenSSH 一芜茵、CA和證書 (一) PKI(Public Key Infr...
    哈嘍別樣閱讀 1,391評(píng)論 0 0
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法倡蝙,內(nèi)部類的語法九串,繼承相關(guān)的語法,異常的語法寺鸥,線程的語...
    子非魚_t_閱讀 31,625評(píng)論 18 399
  • 有一朋友很瘦蒸辆,瘦不稀奇,關(guān)鍵是穩(wěn)定析既,她的體重幾年以來都維持在一個(gè)數(shù)字,幾乎可用來檢驗(yàn)體重秤的準(zhǔn)確與否谆奥。也許你會(huì)說:...
    x123閱讀 368評(píng)論 0 0