"Peer name X.X.X.X is not in peer certificate" 오류 해결 (Python, Go, gRPC)
"Peer name X.X.X.X is not in peer certificate" 오류 해결 (Python, Go, gRPC)
gRPC 클라이언트와 서버 간 연결 시 발생하는 "Peer name X.X.X.X is not in peer certificate" 오류는 클라이언트가 서버의 TLS 인증서에 CN(Common Name) 또는 SAN(Subject Alternative Name)으로 지정된 호스트 이름과 연결하려는 서버의 호스트 이름이 일치하지 않을 때 발생합니다.
해결 방법:
-
서버 인증서 확인:
- 서버 인증서의 CN 또는 SAN에 올바른 호스트 이름이 포함되어 있는지 확인합니다.
- 서버 인증서가 최신인지 확인합니다.
-
클라이언트 설정:
grpc.ssl_target_name_override
옵션을 사용하여 클라이언트가 연결하려는 서버의 호스트 이름을 명시적으로 설정합니다.insecure
옵션을 사용하여 TLS 인증 검증을 비활성화합니다. 주의: 프로덕션 환경에서는 사용하지 않는 것이 좋습니다.
언어별 해결 방법:
Python:
channel = grpc.secure_channel(
'localhost:50051',
grpc.ssl_credentials_for_certificate_file(
'/path/to/server.crt'
),
options=[
('grpc.ssl_target_name_override', 'localhost')
]
)
Go:
opts := []grpc.DialOption{
grpc.WithTransportCredentials(
grpc.NewClientTLSFromCert(
caCertPool,
"localhost",
),
),
grpc.WithAuthority("localhost"),
}
conn, err := grpc.Dial("localhost:50051", opts...)
예제 코드
Python
import grpc
# 서버 인증서
server_crt_path = '/path/to/server.crt'
# 채널 설정
channel = grpc.secure_channel(
'localhost:50051',
grpc.ssl_credentials_for_certificate_file(
server_crt_path
),
options=[
('grpc.ssl_target_name_override', 'localhost')
]
)
# Stub 생성
stub = SomeServiceStub(channel)
# RPC 호출
response = stub.SomeMethod(SomeRequest())
# 채널 종료
channel.close()
Go
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"path/filepath"
)
const (
address = "localhost:50051"
)
type SomeServiceClient struct {
client SomeService
}
func NewSomeServiceClient(conn *grpc.ClientConn) *SomeServiceClient {
return &SomeServiceClient{
client: NewSomeServiceClient(conn),
}
}
func (c *SomeServiceClient) SomeMethod(ctx context.Context, req *SomeRequest) (*SomeResponse, error) {
return c.client.SomeMethod(ctx, req)
}
func main() {
// 서버 인증서
caCertPool, err := credentials.NewClientCACertPoolFromFile(filepath.Join("..", "..", "certs", "ca.crt"))
if err != nil {
fmt.Println("failed to load CA certificate:", err)
return
}
// 채널 설정
opts := []grpc.DialOption{
grpc.WithTransportCredentials(
credentials.NewTLS(&tls.Config{
RootCAs: caCertPool,
ServerName: "localhost",
}),
),
grpc.WithAuthority("localhost"),
}
conn, err := grpc.Dial(address, opts...)
if err != nil {
fmt.Println("failed to dial:", err)
return
}
defer conn.Close()
// 클라이언트 생성
client := NewSomeServiceClient(conn)
// RPC 호출
ctx := context.Background()
req := &SomeRequest{
// ...
}
resp, err := client.SomeMethod(ctx, req)
if err != nil {
fmt.Println("failed to call RPC:", err)
return
}
// 응답 처리
fmt.Println("Response:", resp)
}
"Peer name X.X.X.X is not in peer certificate" 오류 해결을 위한 대체 방법
- 서버 인증서의 CN 또는 SAN을 클라이언트가 연결하려는 서버의 호스트 이름과 일치하도록 변경합니다.
DNS 설정:
- 클라이언트가 서버 인증서의 CN 또는 SAN에 지정된 호스트 이름을 올바르게 확인하도록 DNS 설정을 변경합니다.
로컬 인증서 저장소 사용:
- 서버 인증서를 클라이언트의 로컬 인증서 저장소에 추가하여 인증 검증 과정을 생략합니다. 주의: 보안 위험이 있을 수 있습니다.
인증서 검증 비활성화:
mTLS 비활성화:
- 서버와 클라이언트 모두에서 mTLS(mutual TLS)을 비활성화합니다. 주의: 보안 수준이 낮아집니다.
주의 사항:
- 위의 대체 방법은 보안 수준을 낮출 수 있습니다. 프로덕션 환경에서는 사용하지 않는 것이 좋습니다.
- 최적의 해결 방법은 서버 인증서 CN/SAN을 변경하거나 DNS 설정을 조정하는 것입니다.
추가 정보:
- 특정 언어 또는 프레임워크에 대한 자세한 내용은 해당 언어/프레임워크의 공식 문서를 참조하십시오.
python go grpc