Requests: μ„€μΉ˜λœ μΈμ¦μ„œ, REQUESTS_CA_BUNDLE ν™˜κ²½ λ³€μˆ˜ μ„€μ •, μ—¬μ „νžˆ SSL 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€.

에 λ§Œλ“  2013λ…„ 07μ›” 25일  Β·  10μ½”λ©˜νŠΈ  Β·  좜처: psf/requests

ν›„λ“œ μ•„λž˜μ—μ„œ μš”μ²­μ„ μ‚¬μš©ν•˜λŠ” jenkinsapi λͺ¨λ“ˆμ„ μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. SSL을 μ‚¬μš©ν•˜λŠ” jenkins μ„œλ²„λ₯Ό 가리킀며 μ¦‰μ‹œ μ‚¬μš©ν•˜λ €κ³  ν•˜λ©΄ λ‹€μŒκ³Ό 같은 κ²°κ³Όκ°€ λ‚˜νƒ€λ‚©λ‹ˆλ‹€.

SSLError: [Errno 1] _ssl.c:504: error:14090086 :SSL 루틴:SSL3_GET_SERVER_CERTIFICATE :μΈμ¦μ„œ 확인 μ‹€νŒ¨

jenkinsapiλŠ” verify=Falseλ₯Ό μ„€μ •ν•˜λŠ” 후크λ₯Ό μ œκ³΅ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. jenkins μ„œλ²„μ—μ„œ μΈμ¦μ„œλ₯Ό μ €μž₯ν•˜κ³  이λ₯Ό 가리킀도둝 REQUESTS_CA_BUNDLE ν™˜κ²½ λ³€μˆ˜λ₯Ό μ„€μ •ν•˜λ €κ³  μ‹œλ„ν–ˆμ§€λ§Œ μ—¬μ „νžˆ λ™μΌν•œ 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” λ˜ν•œ certifiλ₯Ό μ„€μΉ˜ν•˜λ €κ³  μ‹œλ„ν–ˆμ§€λ§Œ 차이가 μ—†μŠ΅λ‹ˆλ‹€.

jenkinsapi μ½”λ“œλ₯Ό ν•΄ν‚Ήν•  수 μžˆλ‹€λŠ” 것을 μ•Œκ³  μžˆμ§€λ§Œ λ‚΄ μ½”λ“œμ˜ λͺ¨λ“  μ‚¬μš©μžκ°€ λ™μΌν•œ μž‘μ—…μ„ μˆ˜ν–‰ν•΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— λ§Œμ‘±μŠ€λŸ½μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λ‚΄κ°€ λ­”κ°€λ₯Ό κ°„κ³Όν•˜κ³  μžˆμŠ΅λ‹ˆκΉŒ?

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

λ™μΌν•œ λ¬Έμ œκ°€ λ°œμƒν–ˆκ³  SSL μΈμ¦μ„œ 확인 μ‹€νŒ¨ λ¬Έμ œκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. boto3 μ½”λ“œλ₯Ό κ²€ν† ν•˜μ—¬ REQUESTS_CA_BUNDLE이 μ„€μ •λ˜μ§€ μ•Šμ•˜μœΌλ―€λ‘œ μˆ˜λ™μœΌλ‘œ μ„€μ •ν•˜μ—¬ 두 문제λ₯Ό λͺ¨λ‘ μˆ˜μ •ν–ˆμŠ΅λ‹ˆλ‹€.

from boto3.session import Session
import os

# debian
os.environ['REQUESTS_CA_BUNDLE'] = os.path.join(
    '/etc/ssl/certs/',
    'ca-certificates.crt')
# centos
#   'ca-bundle.crt')

aws-cli의 경우 ~/.bashrcμ—μ„œ REQUESTS_CA_BUNDLE을 μ„€μ •ν•˜λ©΄ 이 λ¬Έμ œκ°€ 해결될 것 κ°™μŠ΅λ‹ˆλ‹€(λ‚΄ aws-cliκ°€ 없이 μž‘λ™ν•˜κΈ° λ•Œλ¬Έμ— ν…ŒμŠ€νŠΈλ˜μ§€ μ•ŠμŒ).

REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt # ca-bundle.crt
export REQUESTS_CA_BUNDLE

λͺ¨λ“  10 λŒ“κΈ€

μ €μž₯된 μΈμ¦μ„œκ°€ μ–΄λ–»κ²Œ μƒκ²ΌλŠ”μ§€ λ³΄μ—¬μ£Όμ‹œκ² μŠ΅λ‹ˆκΉŒ? 여기에 κ°„λ‹¨νžˆ 뢙여넣을 수 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.

응닡해 μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€. μΈμ¦μ„œλ₯Ό λ‹€μ‹œ μ €μž₯ν–ˆκ³  ν˜„μž¬ μž‘λ™ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

제길! λ‚΄κ°€ λ„ˆλ¬΄ 빨리 λ§ν–ˆλ‹€. λ‹€μŒμ€ μΈμ¦μ„œμž…λ‹ˆλ‹€.

-----μΈμ¦μ„œ μ‹œμž‘-----
MIIGQDCCBSigAwIBAgIKWQnHpQAAAAAIzjANBgkqhkiG9w0BAQUFADBZMRMwEQYK
CZImiZPyLGQBGRYDY29tMRQwEgYKCZImiZPyLGQBGRYEZWJheTEUMBIGCgmSJomT
8ixkARkWBGNvcnAxFjAUBgNVBAMTDUFNRVItU1NMQ0EtMDIwHhcNMTIxMTE4MDUz
MTA4WhcNMTQxMTE4MDUzMTA4WjB1MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2Fs
awZvcm5pYTERMA8GA1UEBxMIU2FuIEpvc2UxFDASBgNVBAoTC1BheVBhbCBJbmMu
MQwwCgYDVQQLEwNDRUkxGjAYBgNVBAMTEWZ1c2lvbi5wYXlwYWwuY29tMIIBIjan
BgkqhkiG9w0BAQEFAOCAQ8AMIIBCgKCAQEAwOZj4ezQ/k5vTU6E63uNsP+LZjeg
4kTEUwSzFsRj3NImQdfOrQ7W7S386ep2EZZqmjevO6HBzkaXaYYQ0GSqthdspd53
A8GnLi0q43oFy+kyAc2ItAM0SH/GOt0J+5EUdS12S821WMiwebHInSHINAjexAHN
Sm87yXCyO8mZ3Jzc3+PFraveF9WFmE0NLZUDpEMxq17K3/6iGLsVO/YZkUpaAXNJ
962fGrIZ4xcvK//S903ehloKwQnRCgtNoGCmvsoDftbYye6LfRh/rH3xWFXIUmWG
Wib27ZwAgbyxz2FPcexie4FB/IzbH2l9Tp5rzGWfs1159VmVhQ/L3EJIDQIDAQAB
o4IC7DCCAugwHQYDVR0OBBYEFMkZJD5QaahE21k37UvPIP1VmZ1SMB8GA1UdIwQY
MBAAFLI24M3s4ViBTJbTf1lWAEsUzehVMIIBDQYDVR0fBIIBBDCCAQAwgf2ggfqg
gfeGgb9sZGFwOi8vL0NOPUFNRVItU1NMQ0EtMDIsQ049QU1FUi1TU0xDQS0wMixD
Tj1DRFAsQ049UHVibGljJTIwS2V5JTIwU2VydmljZXMsQ049U2VydmljZXMsQ049
Q29uZmlndXJhdGlvbixEQz1jb3JwLERDPWViYXksREM9Y29tP2NlcnRpZmljYXRl
UmV2b2NhdGlvbkxpc3Q/YmFzZT9vYmplY3RDbGFzcz1jUkxEaXN0cmlidXRpb25Q
b2ludIYzaHR0cDovL3BraS5jb3JwLmViYXkuY29tL0NlcnREYXRhL0FNRVItU1NM
Q0EtMDIuY3JsMIIBTgYIKwYBBQUHAQEEggFAMIIBPDCBsQYIKwYBBQUHMAKGgaRs
ZGFwOi8vL0NOPUFNRVItU1NMQ0EtMDIsQ049QUlBLENOPVB1YmxpYyUyMEtleSUy
MFNlcnZpY2VzLENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9Y29ycCxE
Qz1lYmF5LERDPWNvbT9jQUNlcnRpZmljYXRlP2Jhc2U/b2JqZWN0Q2xhc3M9Y2Vy
dGlmaWNhdGlvbkF1dGhvcml0eTBbBggrBgEFBQcwAoZPaHR0cDovL3BraS5jb3Jw
LmViYXkuY29tL0NlcnREYXRhL0FNRVItU1NMQ0EtMDIuY29ycC5lYmF5LmNvbV9B
TUVSLVNTTENBLTAyLmNydDapBggrBgEFBQcwAYYdaHR0cDovL3BraS5jb3JwLmVi
YXkuY29tL29jc3AwIQYJKwYBBAGCNxQCBBQeEgBXAGUAYgBTAGUAcgB2AGUAcjAL
BgNVHQ8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQEFBQAD
ggEBAFj5s9SdtRpXLz03BjPFsDvQPzoyML9ngHL5zyYMlotUpD7d+aO41Q2E2+LO
REFbd3NAnLT3MfWMHAxNaZ4TRUog1fFJmLJxHTBax5fpmY8YAhiPjQIO+IZOUZO3
4lAwXKsq4ylWS2tlbxL56mPngN2EzLisWgIZqJSx9zd1K/LvKyvs/R3wxBerhTN5
LyHFf9/ByUhaqgIE8jydM4qiS8o3zxjrPAIbi6lnZjktkguYTSAKDoHb17BkNoPr
mU1xDtD1/FuX22dfHpqmJSYVubPVfUTvGB3julT2GNNREoHsQI7wmgFBMaTdvJq
42DUnHIK0pdMzb2urxL/toZ3mHY=
-----μ’…λ£Œ 증λͺ…μ„œ--------

역좔적(κ°€μž₯ 졜근 호좜 λ§ˆμ§€λ§‰):
파일 "goals.py", 3ν–‰,
J = api.Jenkins('https://fusion.[νŽΈμ§‘λ¨].com/jenkins/')
파일 "C:\python27\lib\site-packages\jenkinsapi\jenkins.py", 35ν–‰, init
μ  ν‚¨μŠ€λ² μ΄μŠ€. μ΄ˆκΈ°ν™” (자체, baseurl)
파일 "C:\python27\lib\site-packages\jenkinsapi\jenkinsbase.py", 27ν–‰, μ΄ˆκΈ°ν™”
self.poll()
μ„€λ¬Έ μ‘°μ‚¬μ—μ„œ "C:\python27\lib\site-packages\jenkinsapi\jenkinsbase.py" 파일, 49ν–‰
self._data = self._poll()
파일 "C:\python27\lib\site-packages\jenkinsapi\jenkinsbase.py", 53ν–‰, _poll
λ°˜ν™˜ self.get_data(url)
get_data의 파일 "C:\python27\lib\site-packages\jenkinsapi\jenkinsbase.py", 57ν–‰
응닡 = requester.get_url(url)
get_url의 "C:\python27\lib\site-packages\jenkinsapi\utils\requester.py" 파일, 59ν–‰
μš”μ²­μ„ λ°˜ν™˜ν•©λ‹ˆλ‹€ .get (url,








파일 "C:\python27\lib\site-packages\requests\adapters.py", 331ν–‰, 보내기
SSLError(e) λ°œμƒ
requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:14090086 :SSL 루틴:SSL3_GET_SERVER_CERTIFICATE :μΈμ¦μ„œ 확인 μ‹€νŒ¨

jenkinsapiλ₯Ό κ±°μΉ˜μ§€ μ•Šκ³  μš”μ²­μ„ μ‚¬μš©ν•˜μ—¬ 직접 연결을 μ‹œλ„ν•  수 μžˆμ§€λ§Œ μΈμ¦μ„œλ₯Ό μš”μ²­μ— μ•ˆμ „ν•˜κ²Œ 전달할 수 μžˆμŠ΅λ‹ˆλ‹€.

r=requests.get(url,verify=certfile)

SSLError: [Errno 1] _ssl.c:504: error:14090086 :SSL 루틴:SSL3_GET_SERVER_CERTIFICATE :μΈμ¦μ„œ 확인 μ‹€νŒ¨

r=requests.get(url,cert=certfile)

SSLError: [Errno 336265225] _ssl.c:351: error:140B0009 :SSL 루틴:SSL_CTX_use_PrivateKey_file :PEM lib

개인 ν‚€κ°€ μžˆμ–΄μ•Ό ν•œλ‹€λŠ” λœ»μΈκ°€μš”? μ„œλ²„ μ†Œμœ μžκ°€ ν—ˆμš©ν• μ§€ μ˜μ‹¬λ©λ‹ˆλ‹€.

μ£„μ†‘ν•©λ‹ˆλ‹€. 두 번째 뢀뢄은 λ¬΄μ‹œν•˜μ‹­μ‹œμ˜€. "cert"λ₯Ό μ§€μ •ν•˜λŠ” 것은 μ—¬κΈ°μ„œ λ¬Έμ œκ°€ μ•„λ‹Œ μ„œλ²„μ— μžμ‹ μ„ μΈμ¦ν•˜λŠ” κ²ƒμž„μ„ μ•Œμ•˜μŠ΅λ‹ˆλ‹€.

이제 μš°λ¦¬λŠ” λ¬Έμ œκ°€ μΈμ¦μ„œμ— μžˆλ‹€λŠ” 것을 μ•Œκ³  μžˆμŠ΅λ‹ˆλ‹€ :-)
μΈμ¦μ„œκ°€ μ„œλ²„ μžμ²΄κ°€ μ•„λ‹ˆλΌ CAμ—μ„œ μ œκ³΅λ˜λŠ” 경우: μΆ”λ ₯ 체인이 μ™„λ£Œλ˜μ—ˆμŠ΅λ‹ˆκΉŒ?
μΈμ¦μ„œλ₯Ό 내보낸 λΈŒλΌμš°μ €μ— 이 체인이 ν‘œμ‹œλ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.
μΈμ¦μ„œ μš”μ²­μ„ ν™•μΈν•˜λ €λ©΄ μ™„μ „ν•œ 체인이 ν•„μš”ν•©λ‹ˆλ‹€. λ§ˆμ§€λ§‰ μš”μ†ŒλŠ” μ„œλ²„μ—μ„œ μ „μ†‘λ˜λ©° 루트 μΈμ¦μ„œλ§Œ νŒŒμΌμ— μ €μž₯ν–ˆλ‹€κ³  κ°€μ •ν•©λ‹ˆλ‹€.
λ£¨νŠΈμ™€ 리프 μ‚¬μ΄μ—λŠ” μ—¬μ „νžˆ λͺ¨λ“  μΈμ¦μ„œκ°€ ν•„μš”ν•©λ‹ˆλ‹€. 그것듀은 리프 μΈμ¦μ„œμ™€ ν•¨κ»˜ μ„œλ²„μ—μ„œ λ³΄λ‚΄κ±°λ‚˜ μΈμ¦μ„œ νŒŒμΌμ— μΆ”κ°€ν•  수 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.

κ°μ‚¬ν•©λ‹ˆλ‹€-λ“œλ””μ–΄ μž‘λ™ν•˜κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€! μš”μ•½ν•˜λ©΄ 이것이 λ‹€λ₯Έ μ‚¬λžŒμ—κ²Œ 도움이 λ˜λŠ” 경우: 체인의 λͺ¨λ“  μΈμ¦μ„œλ₯Ό μ„œλ²„ μžμ²΄μ—μ„œ 루트둜 내보내고 각 μΈμ¦μ„œλ₯Ό base64 ν˜•μ‹μœΌλ‘œ μ €μž₯ν•œ λ‹€μŒ λͺ¨λ“  μΈμ¦μ„œλ₯Ό 단일 νŒŒμΌμ— λ³΅μ‚¬ν•˜κ³  ν™˜κ²½μ„ μ„€μ •ν•΄μ•Ό ν–ˆμŠ΅λ‹ˆλ‹€. REQUESTS_CA_BUNDLE λ³€μˆ˜λ₯Ό μ§€μ •ν•©λ‹ˆλ‹€.

도움을 μ£Όμ…”μ„œ λ‹€μ‹œ ν•œ 번 κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€!

λ‹€λ₯Έ Google μ§μ›μ˜ 경우 λ‹€μŒμ„ μ‚¬μš©ν•˜μ—¬ jenkinsapiμ—μ„œ SSL 확인을 λΉ„ν™œμ„±ν™”ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

from jenkinsapi.jenkins import Jenkins
from jenkinsapi.utils.requester import Requester

j = Jenkins(base_url, requester=Requester(username, password, baseurl=base_url, ssl_verify=False))

λ™μΌν•œ λ¬Έμ œκ°€ λ°œμƒν–ˆκ³  SSL μΈμ¦μ„œ 확인 μ‹€νŒ¨ λ¬Έμ œκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. boto3 μ½”λ“œλ₯Ό κ²€ν† ν•˜μ—¬ REQUESTS_CA_BUNDLE이 μ„€μ •λ˜μ§€ μ•Šμ•˜μœΌλ―€λ‘œ μˆ˜λ™μœΌλ‘œ μ„€μ •ν•˜μ—¬ 두 문제λ₯Ό λͺ¨λ‘ μˆ˜μ •ν–ˆμŠ΅λ‹ˆλ‹€.

from boto3.session import Session
import os

# debian
os.environ['REQUESTS_CA_BUNDLE'] = os.path.join(
    '/etc/ssl/certs/',
    'ca-certificates.crt')
# centos
#   'ca-bundle.crt')

aws-cli의 경우 ~/.bashrcμ—μ„œ REQUESTS_CA_BUNDLE을 μ„€μ •ν•˜λ©΄ 이 λ¬Έμ œκ°€ 해결될 것 κ°™μŠ΅λ‹ˆλ‹€(λ‚΄ aws-cliκ°€ 없이 μž‘λ™ν•˜κΈ° λ•Œλ¬Έμ— ν…ŒμŠ€νŠΈλ˜μ§€ μ•ŠμŒ).

REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt # ca-bundle.crt
export REQUESTS_CA_BUNDLE
이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰