Как правильно реализовать и развернуть безопасное сервер начальной загрузки Leshan с PSK Over Coaps?JAVA

Программисты JAVA общаются здесь
Anonymous
Как правильно реализовать и развернуть безопасное сервер начальной загрузки Leshan с PSK Over Coaps?

Сообщение Anonymous »

🔧 То, что я пытаюсь сделать
Я настраиваю сервер начальной загрузки Leshan (Coaps, DTLS-PSK) для надежных устройств, основанных на их IMEI. Сервер написан на Java с использованием Maven и развернута через Docker, позади Traefik 2.8. Я также использую базу данных MySQL для динамического управления PSK Identity + Keys. /> Использует аутентификацию PSK (идентификация, ключ) < /p>
Получает учетные данные устройства (ID PSK, ключ PSK) из MySQL < /p>
Отвечает динамической конфигурацией для основного сервера DM < /p>
Подключить клиент с: < /p>

Код: Выделить всё

java -jar leshan-demo-client.jar \
-b \
-u coaps://141.94.31.102:5684 \
-i squid_bootstrap \
-p da4b619ba5205387 \
-n 353888283470990
< /code>
💻 мой сервер Java (QuickStart maven) < /p>
package fr.akensys;

import java.util.Collections;
import java.util.List;
import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServer;
import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServerBuilder;
import org.eclipse.leshan.server.security.SecurityInfo;
import org.eclipse.leshan.server.security.BootstrapSecurityStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.github.cdimascio.dotenv.Dotenv;

public class App {
private static final Logger LOG = LoggerFactory.getLogger(App.class);
private static final Dotenv ENV = Dotenv.load();

public static void main(String[] args) {
try {
LOG.info("=============================================================================================================");
LOG.info("Démarrage du serveur Bootstrap Leshan");

BootstrapSecurityStore securityStore = createSecurityStore();

LeshanBootstrapServer server = new LeshanBootstrapServerBuilder()
.setConfigStore(new DatabaseConfigStore())
.setSecurityStore(securityStore)
.build();

server.start();
LOG.info("Serveur démarré - CoAP:5683 / CoAPS:5684");

} catch (Exception e) {
LOG.error("Erreur critique", e);
System.exit(1);
}
}

private static BootstrapSecurityStore createSecurityStore() {
final String bootstrapIdentity = ENV.get("BOOTSTRAP_PSK_IDENTITY");
final byte[] bootstrapKey = ENV.get("BOOTSTRAP_PSK_KEY").getBytes();

return new BootstrapSecurityStore() {
@Override
public List getAllByEndpoint(String endpoint) {
return Collections.singletonList(
SecurityInfo.newPreSharedKeyInfo(endpoint, bootstrapIdentity, bootstrapKey)
);
}

@Override
public SecurityInfo getByIdentity(String pskIdentity) {
return bootstrapIdentity.equals(pskIdentity)
? SecurityInfo.newPreSharedKeyInfo(null, bootstrapIdentity, bootstrapKey)
: null;
}
};
}
}

package fr.akensys;

import java.security.SecureRandom;
import java.sql.*;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.leshan.core.SecurityMode;
import org.eclipse.leshan.core.request.Identity;
import org.eclipse.leshan.server.bootstrap.*;
import org.eclipse.leshan.server.bootstrap.BootstrapConfig.ServerSecurity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.github.cdimascio.dotenv.Dotenv;

public class DatabaseConfigStore implements EditableBootstrapConfigStore {
private final Connection conn;
private final Dotenv env;
private final Map cache = new ConcurrentHashMap();
private static final Logger LOG = LoggerFactory.getLogger(DatabaseConfigStore.class);

public DatabaseConfigStore() throws SQLException {
this.env = Dotenv.load();
this.conn = DriverManager.getConnection(
env.get("DB_URL"),
env.get("DB_USER"),
env.get("DB_PASSWORD")
);

if (conn.isValid(5)) {
LOG.info("Connexion à la base OK !");
} else {
LOG.error("La connexion à la base a échoué");
throw new SQLException("Connexion invalide");
}

createTableIfNotExists();

try {
String testImei = "353888283470990";
String testPskId = "dm-" + testImei;
String testKeyHex = "7f1e2d3c4b5a6978";

String sql = "INSERT INTO device (imei, device_psk_id, device_psk_key) " +
"VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE "  +
"device_psk_key=VALUES(device_psk_key), last_updated=NOW()";

try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, testImei);
stmt.setString(2, testPskId);
stmt.setString(3, testKeyHex);
stmt.executeUpdate();
LOG.info("Donnée de test insérée : IMEI={}, PSK={}", testImei, testKeyHex);
}
} catch (SQLException e) {
LOG.warn("Erreur lors de l'insertion de test (peut être normal si existe déjà)", e);
}
}

private static byte[] hexStringToByteArray(String hex) {
int len = hex.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) 

4.0.0
fr.akensys
my-leshan-bootstrap-standalone
1.0-SNAPSHOT


UTF-8
11
${java.version}
${java.version}




org.eclipse.leshan
leshan-server-cf
1.5.0


junit
junit
4.11
test


org.slf4j
slf4j-simple
1.7.30


mysql
mysql-connector-java
8.0.28


io.github.cdimascio
dotenv-java
3.0.0







maven-compiler-plugin
3.8.0

${java.version}
${java.version}




org.apache.maven.plugins
maven-shade-plugin
3.4.1


package

shade


${project.artifactId}-${project.version}-standalone


fr.akensys.App




*:*

META-INF/*.SF
META-INF/*.DSA
META-INF/*.RSA












# Configuration Bootstrap
BOOTSTRAP_PSK_IDENTITY=squid_bootstrap
BOOTSTRAP_PSK_KEY=da4b619ba5205387

# Configuration Serveur Principal
DM_SERVER_URL=coaps://prod-server.com
DM_SERVER_ID=1

# Configuration Base de Données
DB_URL=jdbc:mysql://localhost:3306/leshan
DB_USER=root
DB_PASSWORD=root
PSK_KEY_LENGTH=8
< /code>
🐳 Docker развертывание < /p>
dockerfile (in /server) < /p>
dockerfile
Copy
Edit
FROM eclipse-temurin:17-jre-jammy
WORKDIR /app
COPY .  .
CMD ["java", "-jar", "my-leshan-bootstrap-standalone-1.0-SNAPSHOT-standalone.jar"]
EXPOSE 5683/udp 5684/udp
< /code>
docker-compose.yml
services:
mysql:
image: mysql:8.0
...
ports:
- "3306:3306"
networks:
- traefik-proxy

bootstrap:
build: ./server
...
labels:
- "traefik.udp.routers.leshan-coaps.entrypoints=leshan-coaps"
- "traefik.udp.routers.leshan-coaps.service=leshan-coaps"
- "traefik.udp.services.leshan-coaps.loadbalancer.server.port=5684"
ports:
- "5684:5684/udp"
networks:
- traefik-proxy
< /code>
traefik config (режим UDP) < /p>
entryPoints:
leshan-coaps:
address: ":5684/udp"

providers:
docker:
network: traefik-proxy
< /code>
❗ Проблема
Когда я запускаю клиент, я вижу: < /p>
Leshan client[endpoint:353888283470990] started.
Trying to start bootstrap session to coaps://141.94.31.102:5684 ...
DTLS Full Handshake initiated by client : STARTED ...
DTLS Full Handshake initiated by client : FAILED
(Handshake flight 1 failed! Stopped by timeout after 4 retransmissions!)
Unable to start bootstrap session: Timeout.
< /code>
❓ Вопросы < /p>
[list]
[*] Является ли моя реализация Java сервера Bootstrap для аутентификации PSK?
особенно: < /li>
< /ol>
Использование DeviewInfo.newpreshareAnfo ( / /ol>
ancaredInfo.newpreshareAnfo ( / /ol>
< /p> dyname Хранение device_psk_key на IMEI < /p>
генерирование BootstrapConfig с помощью SecurityMode = PSK и правильного ключа < /p>

 Является ли мой Docker & Traefik Interferup с помощью DTLS Handshake? Раскрытый
[/list]
Traefik Config включает в себя правильные точки входа для UDP 
Метки кажутся нормальными, но я не уверен, что UDP -пропуск через Traefik является надежным 
Я должен избегать использования Traefik для coaps/udp и map непосредственно с:   br/>
raefik для coaps/udp и map: 
.ports:
- "5684:5684/udp"
Без траха? /> Пробое с и без Traefik < /p>
🛠 среда
vps ubuntu 22.04 (ovh) < /p>
java 17 (temurin) < /p>
eclipse leshan 1.0 snapshot < /p>
docker compose compose compose compose compose 1. /> traefik 2.8 < /p>
Клиент и сервер на той же машине < /p>
Любые идеи о том, что не так с рукопожатием DTLS или как правильно структурировать сервер для безопасной начальной загрузки?
Спасибо < /p>

Подробнее здесь: https://stackoverflow.com/questions/796 ... with-psk-o

Вернуться в «JAVA»