← Назад к вопросам
Возможна ли реализация https коммуникации между сервисами, развернутыми локально?
2.0 Middle🔥 101 комментариев
#REST API и микросервисы#Безопасность
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
HTTPS коммуникация между локальными сервисами
Да, абсолютно возможно! На самом деле, это отличная практика для development окружения, чтобы избежать неприятных сюрпризов при деплое на production.
Способ 1: Self-signed сертификаты
Это самый быстрый способ для локальной разработки.
Создание самоподписанного сертификата
# Создаём приватный ключ и сертификат
keytool -genkey -alias localhost -keyalg RSA -keysize 2048 -keystore keystore.p12 -storepass password123 -validity 365
# Ответьте на вопросы (CN должен быть localhost или IP адрес)
What is your first and last name?
[Unknown]: localhost
What is the name of your organizational unit?
[Unknown]: dev
What is the name of your organization?
[Unknown]: MyCompany
What is the name of your City or Locality?
[Unknown]: Moscow
What is the name of your State or Province?
[Unknown]: Moscow
What is the two-letter country code for this unit?
[Unknown]: RU
Is CN=localhost, OU=dev, O=MyCompany, L=Moscow, ST=Moscow, C=RU correct?
[yes]: yes
Конфигурация Spring Boot
# application.yml
server:
port: 8443
ssl:
key-store: classpath:keystore.p12
key-store-password: password123
key-store-type: PKCS12
key-alias: localhost
Запуск
# Сервис теперь доступен по HTTPS
curl --insecure https://localhost:8443/api/health
# или
curl -k https://localhost:8443/api/health # -k = --insecure
Способ 2: Использование mkcert
Модернее и удобнее. Создаёт сертификаты, которые браузер и curl автоматически доверяют.
Установка
# macOS
brew install mkcert
# Linux
wget https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-amd64
chmod +x mkcert-v1.4.4-linux-amd64
sudo mv mkcert-v1.4.4-linux-amd64 /usr/local/bin/mkcert
# Windows
choco install mkcert
Создание сертификатов
# Инициализируем CA
mkcert -install
# Создаём сертификаты для localhost
mkcert -pkcs12 localhost 127.0.0.1 ::1
# Результат: localhost.p12
Spring Boot конфигурация
server:
port: 8443
ssl:
key-store: classpath:localhost.p12
key-store-password: changeit
key-store-type: PKCS12
key-alias: localhost
Теперь работает без --insecure!
# Работает как обычное HTTPS
curl https://localhost:8443/api/health
# No certificate warnings!
Способ 3: Docker Compose с HTTPS
version: '3.8'
services:
service-a:
image: myapp:latest
ports:
- "8443:8443"
environment:
- SERVER_SSL_ENABLED=true
- SERVER_SSL_KEY_STORE=/etc/ssl/keystore.p12
- SERVER_SSL_KEY_STORE_PASSWORD=password123
volumes:
- ./keystore.p12:/etc/ssl/keystore.p12
networks:
- backend
service-b:
image: myapp:latest
ports:
- "9443:8443"
environment:
- SERVICE_A_URL=https://service-a:8443
- SSL_VERIFY_HOSTNAME=false # Для самоподписанных
depends_on:
- service-a
networks:
- backend
networks:
backend:
driver: bridge
Способ 4: RestTemplate/WebClient с игнорированием сертификатов
Когда нужно обращаться к HTTPS сервису с самоподписанным сертификатом:
RestTemplate (старый способ)
public class SslUtils {
public static RestTemplate createTrustAllRestTemplate() throws Exception {
// Создаём SSL контекст, который доверяет всем сертификатам
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(
null,
new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}},
new SecureRandom()
);
// Также игнорируем hostname verification
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create()
.setSSLContext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
HttpClient httpClient = httpClientBuilder.build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(factory);
}
}
// Использование
@Configuration
public class RestClientConfig {
@Bean
public RestTemplate restTemplate() throws Exception {
return SslUtils.createTrustAllRestTemplate();
}
}
WebClient (современный способ)
@Configuration
public class WebClientConfig {
@Bean
public WebClient webClient() throws Exception {
// SSL контекст
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(
null,
new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}},
new SecureRandom()
);
HttpClient httpClient = HttpClient.create()
.secure(sslSpec -> sslSpec
.sslContext(sslContext)
.handshakeTimeout(Duration.ofSeconds(10))
);
return WebClient.builder()
.clientConnector(new ReactorNettyClientRequestFactory(
HttpClient.create()
.secure(sslSpec -> sslSpec
.sslContext(sslContext)
)
))
.build();
}
}
Ещё проще: через Spring Boot свойства
# application.yml
spring:
https:
proxyProtocol: true
feign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 5000
@FeignClient(
name = "service-a",
url = "https://localhost:8443",
configuration = FeignClientConfig.class
)
public interface ServiceAClient {
@GetMapping("/api/health")
ResponseEntity<String> health();
}
@Configuration
public class FeignClientConfig {
@Bean
public Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
Способ 5: Использование отдельного CA
Для более реалистичного environment:
# 1. Создаём CA
openssl genrsa -out ca-key.pem 2048
openssl req -new -x509 -days 365 -key ca-key.pem -out ca-cert.pem
# 2. Создаём сертификат сервиса
openssl genrsa -out server-key.pem 2048
openssl req -new -key server-key.pem -out server.csr -subj "/CN=localhost"
openssl x509 -req -days 365 -in server.csr -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem
# 3. Конвертируем в PKCS12
openssl pkcs12 -export -in server-cert.pem -inkey server-key.pem -out keystore.p12 -name localhost
Практический пример: микросервисы
// Service A (port 8443)
@RestController
@RequestMapping("/api")
public class ServiceAController {
@GetMapping("/data")
public ResponseEntity<String> getData() {
return ResponseEntity.ok("Data from Service A");
}
}
// Service B (port 9443) - обращается к Service A
@Service
public class ServiceBClient {
@Bean
RestTemplate restTemplate() throws Exception {
return SslUtils.createTrustAllRestTemplate();
}
public String getDataFromServiceA() {
String url = "https://localhost:8443/api/data";
return restTemplate().getForObject(url, String.class);
}
}
Рекомендации
Для разработки:
- Используй mkcert (просто и удобно)
- Или self-signed сертификаты с --insecure
Для тестирования:
- Игнорируй сертификат (как показано выше)
- Используй WebClient с кастомным SSL контекстом
Для production:
- НИКОГДА не игнорируй сертификаты!
- Используй Let's Encrypt или корпоративный CA
- Установи сертификаты в keystore
Заключение
Да, HTTPS локально абсолютно возможно и рекомендуется для:
- Тестирования SSL-зависимого функционала
- Имитирования production environment
- Обнаружения SSL проблем ДО development
Выбирай mkcert, это самый удобный способ.