mTLS ๋?
mTLS๋ "Mutual Transport Layer Security"์ ์ฝ์๋ก, ํด๋ผ์ด์ธํธ์ ์๋ฒ ๊ฐ์ ์ํธ ์ธ์ฆ์ ์ํ TLS(Transport Layer Security) ํ๋กํ ์ฝ์ ํ์ฅ์ด๋ค. ์ผ๋ฐ์ ์ธ TLS๋ ์๋ฒ๋ง ์ธ์ฆํ๋ ๋ฐ๋ฉด, mTLS๋ ํด๋ผ์ด์ธํธ์ ์๋ฒ ๋ชจ๋๊ฐ ์๋ก๋ฅผ ์ธ์ฆํ๋ ๋ฐฉ์์ด๋ค. ์ด๋ฅผ ํตํด ๋ ๋์ ์์ค์ ๋ณด์์ด ์ ๊ณต๋๋ค.
mTLS์ ์๋ ๋ฐฉ์์ ์๋ฒ ์ธ์ฆ, ํด๋ผ์ด์ธํธ ์ธ์ฆ, ์ํธ ์ธ์ฆ ์๋ฃ ๋ก ์งํ๋์ด์ผ ํ๋ค.
1. ์๋ฒ ์ธ์ฆ : ํด๋ผ์ด์ธํธ ์๋ฒ์ SSL/TLS ์ธ์ฆ์๋ฅผ ํ์ธํ์ฌ ์๋ฒ์ ์ ์์ ๊ฒ์ฆํ๋ค. ์ด๋ ์ผ๋ฐ์ ์ธ TLS ์ฐ๊ฒฐ์์ ์ด๋ฃจ์ด์ง๋ ๋จ๊ณ์ด๋ค.
2. ํด๋ผ์ด์ธํธ ์ธ์ฆ : ์๋ฒ ๋ํ ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ์ธ์ฆ์๋ฅผ ์์ฒญํ๋ค. ํด๋ผ์ด์ธํธ๋ ์์ ์ ์ธ์ฆ์๋ฅผ ์๋ฒ์ ์ ์ถํ์ฌ ์ ์์ ์ฆ๋ช ํ๋ค.
3. ์ํธ ์ธ์ฆ ์๋ฃ : ์๋ฒ์ ํด๋ผ์ด์ธํธ๊ฐ ์๋ก์ ์ธ์ฆ์๋ฅผ ํ์ธํ๊ณ ์ ํจ์ฑ์ ๊ฒ์ฆํ๋ฉด, ์ํธ ์ธ์ฆ์ด ์๋ฃ๋๊ณ ์์ ํ ํต์ ์ด ์์๋๋ค.
์งํ
1๏ธโฃ ca ์ธ์ฆ์ ๋ฐ๊ธ
์ธ์ฆ์๋ฅผ ๋ฐ๊ธํ๋ ๊ถํ์ ๊ฐ์ง ์ธ์ฆ ๊ธฐ๊ด(CA)์ ๋ํ๋ธ๋ค.
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt
Common Name(CN) ํ๋์ ๋ฃ์ด์ผํ ๋ด์ฉ : CA์ ์ด๋ฆ ๋๋ ์ญํ ์ ๋ช ํํ ๋ํ๋ด๋ ๊ณ ์ ํ ์๋ณ์๋ฅผ ๋ฃ๋๋ค.
- ์์ : MyCompany Root CA, MyCompany Intermediate CA
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) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:MyCompany Root CA
Email Address []:
2๏ธโฃ server ์ธ์ฆ์ ๋ฐ๊ธ
ํน์ ์๋ฒ(์: ์น ์๋ฒ)์ ๋ํด ๋ฐ๊ธ๋ ์ธ์ฆ์๋ก, ํด๋ผ์ด์ธํธ๊ฐ ์ด ์๋ฒ์ ์ ๊ทผํ ๋ ์๋ฒ์ ์ ์์ ํ์ธํ ์ ์๋ค.
openssl genrsa -out server.key 4096
openssl req -new -key server.key -out server.csr
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -sha256
Common Name(CN) ํ๋์ ๋ฃ์ด์ผํ ๋ด์ฉ : ํด๋น ์๋ฒ๊ฐ ์๋น์คํ๋ ๋๋ฉ์ธ ์ด๋ฆ์ ๋ฃ์ด์ผํ๋ค. ํด๋ผ์ด์ธํธ๊ฐ ์ด ๋๋ฉ์ธ์ ์ ๊ทผํ ๋, CN ๋๋ SAN(Subject Alternative Name) ํ๋์ ์๋ ๋๋ฉ์ธ๊ณผ ์ผ์นํด์ผ ํ๋ค.
- ์์ : yourdomain.com
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) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:yourdomain.com
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
3๏ธโฃ client ์ธ์ฆ์ ๋ฐ๊ธ
ํด๋ผ์ด์ธํธ(์ฌ์ฉ์ ๋๋ ์ฅ์น)์ ์ ์์ ์ธ์ฆํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ ์ธ์ฆ์
openssl genrsa -out client.key 4096
openssl req -new -key client.key -out client.csr
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365 -sha256
Common Name(CN) ํ๋์ ๋ฃ์ด์ผํ ๋ด์ฉ : ํด๋ผ์ด์ธํธ๋ฅผ ์๋ณํ ์ ์๋ ๊ณ ์ ํ ์ด๋ฆ(์: ์ฌ์ฉ์ ์ด๋ฆ, ์ด๋ฉ์ผ ์ฃผ์, ์ฅ์น ์ด๋ฆ)์ ๋ฃ์ด์ผ ํ๋ค.
- ์์ : John Doe, johndoe@example.com, Device-001
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) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:Device-001
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
4๏ธโฃ nginx conf ์์
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /etc/nginx/auth/server.crt;
ssl_certificate_key /etc/nginx/auth/server.key;
ssl_client_certificate /etc/nginx/auth/ca.crt; # ํด๋ผ์ด์ธํธ ์ธ์ฆ์ ํ์ธ์ ์ํ CA ์ธ์ฆ์
ssl_verify_client on; # ํด๋ผ์ด์ธํธ ์ธ์ฆ์ ๊ฒ์ฆ ํ์ฑํ
client_max_body_size 30M;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;
proxy_redirect off;
proxy_pass http://[ip_address]:[port];
charset utf-8;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
}
}
โ ์ฐ๊ฒฐ ํ ์คํธ
ca ์ธ์ฆ์(ca.crt), client ์ธ์ฆ์(client.crt), client ํค(client.key) ์ ๊ฐ์ด ์์ฒญํด์ผ ํ๋ค !
โ ์ธ์ฆ์ ์์ด ์ ๊ทผํ ๊ฒฝ์ฐ

โญ๏ธ ์ธ์ฆ์์ ํจ๊ป curl ์์ฒญ
curl -v --key client.key --cert client.crt --cacert ca.crt https://yourdomain.com
* Rebuilt URL to: https://ddeheart.com/
* Trying [ip address]...
* Connected to yourdomain.com ([ip address]) port 443 (#0)
* found 1 certificates in ca.crt
* found 516 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_256_GCM_SHA384
* server certificate verification OK
* server certificate status verification SKIPPED
* common name: yourdomain.com (matched)
* server certificate expiration date OK
* server certificate activation date OK
* certificate public key: RSA
* certificate version: #1
* subject: C=AU,ST=Some-State,O=Internet Widgits Pty Ltd,CN=yourdomain.com
* start date: Fri, 16 Aug 2024 05:47:35 GMT
* expire date: Sat, 16 Aug 2025 05:47:35 GMT
* issuer: C=AU,ST=Some-State,O=Internet Widgits Pty Ltd,CN=MyCompany Root CA
* compression: NULL
* ALPN, server accepted to use http/1.1
> GET / HTTP/1.1
> Host: yourdomain.com
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.10.3 (Ubuntu)
< Date: Fri, 16 Aug 2024 06:23:02 GMT
< Content-Type: application/json
< Content-Length: 18
< Connection: keep-alive
<
{"Hello":"World"}
* Connection #0 to host yourdomain.com left intact
โญ๏ธ ์ธ์ฆ์์ ํจ๊ป python requests๋ฅผ ์ด์ฉํ ์์ฒญ
import requests
url = "https://yourdomain.com"
cert = ("client.crt", "client.key")
ca_cert = "ca.crt"
response = requests.get(url, cert=cert, verify=ca_cert)
print(response.json())
CN์ ๋์ผํ ๋๋ฉ์ธ์ ์ ๋ ฅํ ๊ฒฝ์ฐ 400 Bad Request๋ก ์ ๊ทผ ๋ถ๊ฐ๋ฅํ๋ค
- ์๋ณ ๋ฌธ์ : ์ธ์ฆ์ ๊ฒ์ฆ ๊ณผ์ ์์ CN ํ๋๊ฐ ๋์ผํ ์ธ์ฆ์๋ค์ด ์์ ๊ฒฝ์ฐ, ํด๋ผ์ด์ธํธ๋ ์๋ฒ๋ ์ด๋ค ์ธ์ฆ์๋ฅผ ๊ตฌ๋ถํ๋ ๋ฐ ์ด๋ ค์์ ๊ฒช์ ์ ์๋ค. ํนํ, ์๋ฒ์ ํด๋ผ์ด์ธํธ ๊ฐ ์ํธ ์ธ์ฆ(mTLS)์์ ํด๋ผ์ด์ธํธ ์ธ์ฆ์๋ฅผ ์๋ฒ ์ธ์ฆ์์ ํผ๋ํ ์ ์๋ค.
- ์ ๋ขฐ ๋ฌธ์ : CA ์ธ์ฆ์, ์๋ฒ ์ธ์ฆ์, ํด๋ผ์ด์ธํธ ์ธ์ฆ์๊ฐ ์๋ก ๋ค๋ฅด๊ฒ ๋ฐ๊ธ๋์ด์ผ ํ๋ฉฐ, ๊ฐ๊ฐ์ ์ญํ ์ ๋ฐ๋ผ ๊ณ ์ ํ CN์ ๊ฐ์ง๋ ๊ฒ์ด ์์น์ด๋ค. ๋์ผํ CN์ ์ฌ์ฉํ๋ฉด ์ธ์ฆ์ ์ฒด๊ณ๊ฐ ๋ณต์กํด์ง๊ณ ์ ๋ขฐ ๋ฌธ์ ๋ฅผ ์ผ๊ธฐํ ์ ์๋ค.
'๐ฉ๐ปโ๐ป' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[MQTT] pc 2๊ฐ ํต์ (python, ์๋ฐฉํฅ ํต์ ) (0) | 2025.02.25 |
---|---|
[MQTT] Mac mosquitto ์ค์น / ์คํ / ์ค์ง (0) | 2025.02.25 |
์ฝ๋ ํ์ง ๊ด๋ฆฌ (0) | 2025.02.20 |