From 7986658bd109aebd4d7ff2f10e8ff3f84744ecbe Mon Sep 17 00:00:00 2001 From: Sergey Date: Wed, 26 Jul 2023 18:21:49 +0000 Subject: [PATCH] Update configuration --- docker/Dockerfile_app | 12 +++--- .../ApplicationConfiguration.java | 17 ++++----- .../configuration/SecurityConfiguration.java | 14 ++----- .../packmate/pcap/AbstractPcapWorker.java | 4 +- .../packmate/pcap/FilePcapWorker.java | 5 ++- .../packmate/pcap/LivePcapWorker.java | 5 ++- .../properties/PackmateProperties.java | 38 +++++++++++++++++++ .../packmate/service/ServicesService.java | 14 ++++--- .../packmate/service/StreamService.java | 6 +-- .../packmate/tasks/OldStreamsCleanupTask.java | 13 +++---- .../packmate/tasks/StartupListener.java | 20 ++++------ .../packmate/tasks/TimeoutStreamsSaver.java | 13 +++---- src/main/resources/application.yml | 37 ++++++++++-------- 13 files changed, 117 insertions(+), 81 deletions(-) create mode 100644 src/main/java/ru/serega6531/packmate/properties/PackmateProperties.java diff --git a/docker/Dockerfile_app b/docker/Dockerfile_app index ac38120..e35243e 100644 --- a/docker/Dockerfile_app +++ b/docker/Dockerfile_app @@ -17,11 +17,13 @@ COPY --from=1 /tmp/compile/build/libs/packmate-*-SNAPSHOT.jar app.jar CMD [ "java", "-Djava.net.preferIPv4Stack=true", "-Djava.net.preferIPv4Addresses=true", \ "-jar", "/app/app.jar", "--spring.datasource.url=jdbc:postgresql://127.0.0.1:65001/packmate", \ "--spring.datasource.password=${DB_PASSWORD}", \ - "--capture-mode=${MODE}", "--pcap-file=${PCAP_FILE}", \ - "--interface-name=${INTERFACE}", "--local-ip=${LOCAL_IP}", "--account-login=${WEB_LOGIN}", \ - "--old-streams-cleanup-enabled=${OLD_STREAMS_CLEANUP_ENABLED}", "--cleanup-interval=${OLD_STREAMS_CLEANUP_INTERVAL}", \ - "--old-streams-threshold=${OLD_STREAMS_CLEANUP_THRESHOLD}", \ - "--account-password=${WEB_PASSWORD}", "--server.port=65000", "--server.address=0.0.0.0" \ + "--packmate.capture-mode=${MODE}", "--packmate.pcap-file=${PCAP_FILE}", \ + "--packmate.interface-name=${INTERFACE}", "--packmate.local-ip=${LOCAL_IP}", \ + "--packmate.web.account-login=${WEB_LOGIN}", "--packmate.web.account-password=${WEB_PASSWORD}", \ + "--packmate.cleanup.enabled=${OLD_STREAMS_CLEANUP_ENABLED}", \ + "--packmate.cleanup.interval=${OLD_STREAMS_CLEANUP_INTERVAL}", \ + "--packmate.cleanup.threshold=${OLD_STREAMS_CLEANUP_THRESHOLD}", \ + "--server.port=65000", "--server.address=0.0.0.0" \ ] EXPOSE 65000 \ No newline at end of file diff --git a/src/main/java/ru/serega6531/packmate/configuration/ApplicationConfiguration.java b/src/main/java/ru/serega6531/packmate/configuration/ApplicationConfiguration.java index 90f35a5..75c9a01 100644 --- a/src/main/java/ru/serega6531/packmate/configuration/ApplicationConfiguration.java +++ b/src/main/java/ru/serega6531/packmate/configuration/ApplicationConfiguration.java @@ -5,19 +5,19 @@ import org.modelmapper.ModelMapper; import org.modelmapper.TypeMap; import org.pcap4j.core.PcapNativeException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationPropertiesScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; import ru.serega6531.packmate.model.Pattern; import ru.serega6531.packmate.model.Stream; -import ru.serega6531.packmate.model.enums.CaptureMode; import ru.serega6531.packmate.model.pojo.StreamDto; import ru.serega6531.packmate.pcap.FilePcapWorker; import ru.serega6531.packmate.pcap.LivePcapWorker; import ru.serega6531.packmate.pcap.NoOpPcapWorker; import ru.serega6531.packmate.pcap.PcapWorker; +import ru.serega6531.packmate.properties.PackmateProperties; import ru.serega6531.packmate.service.ServicesService; import ru.serega6531.packmate.service.StreamService; import ru.serega6531.packmate.service.SubscriptionService; @@ -29,6 +29,7 @@ import java.util.stream.Collectors; @Configuration @EnableScheduling @EnableAsync +@ConfigurationPropertiesScan("ru.serega6531.packmate.properties") public class ApplicationConfiguration { @Bean(destroyMethod = "stop") @@ -36,14 +37,12 @@ public class ApplicationConfiguration { public PcapWorker pcapWorker(ServicesService servicesService, StreamService streamService, SubscriptionService subscriptionService, - @Value("${local-ip}") String localIpString, - @Value("${interface-name}") String interfaceName, - @Value("${pcap-file}") String filename, - @Value("${capture-mode}") CaptureMode captureMode) throws PcapNativeException, UnknownHostException { - return switch (captureMode) { - case LIVE -> new LivePcapWorker(servicesService, streamService, localIpString, interfaceName); + PackmateProperties properties + ) throws PcapNativeException, UnknownHostException { + return switch (properties.captureMode()) { + case LIVE -> new LivePcapWorker(servicesService, streamService, properties.localIp(), properties.interfaceName()); case FILE -> - new FilePcapWorker(servicesService, streamService, subscriptionService, localIpString, filename); + new FilePcapWorker(servicesService, streamService, subscriptionService, properties.localIp(), properties.pcapFile()); case VIEW -> new NoOpPcapWorker(); }; } diff --git a/src/main/java/ru/serega6531/packmate/configuration/SecurityConfiguration.java b/src/main/java/ru/serega6531/packmate/configuration/SecurityConfiguration.java index 606e862..f24f32d 100644 --- a/src/main/java/ru/serega6531/packmate/configuration/SecurityConfiguration.java +++ b/src/main/java/ru/serega6531/packmate/configuration/SecurityConfiguration.java @@ -1,7 +1,6 @@ package ru.serega6531.packmate.configuration; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.event.EventListener; @@ -14,23 +13,18 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; +import ru.serega6531.packmate.properties.PackmateProperties; @Configuration @EnableWebSecurity @Slf4j public class SecurityConfiguration { - @Value("${account-login}") - private String login; - - @Value("${account-password}") - private String password; - @Bean - public InMemoryUserDetailsManager userDetailsService(PasswordEncoder passwordEncoder) { + public InMemoryUserDetailsManager userDetailsService(PackmateProperties properties, PasswordEncoder passwordEncoder) { UserDetails user = User.builder() - .username(login) - .password(passwordEncoder.encode(password)) + .username(properties.web().accountLogin()) + .password(passwordEncoder.encode(properties.web().accountPassword())) .roles("USER") .build(); diff --git a/src/main/java/ru/serega6531/packmate/pcap/AbstractPcapWorker.java b/src/main/java/ru/serega6531/packmate/pcap/AbstractPcapWorker.java index b7d619a..08832ab 100644 --- a/src/main/java/ru/serega6531/packmate/pcap/AbstractPcapWorker.java +++ b/src/main/java/ru/serega6531/packmate/pcap/AbstractPcapWorker.java @@ -52,11 +52,11 @@ public abstract class AbstractPcapWorker implements PcapWorker, PacketListener { protected AbstractPcapWorker(ServicesService servicesService, StreamService streamService, - String localIpString) throws UnknownHostException { + InetAddress localIp) throws UnknownHostException { this.servicesService = servicesService; this.streamService = streamService; - this.localIp = InetAddress.getByName(localIpString); + this.localIp = localIp; BasicThreadFactory factory = new BasicThreadFactory.Builder() .namingPattern("pcap-loop").build(); diff --git a/src/main/java/ru/serega6531/packmate/pcap/FilePcapWorker.java b/src/main/java/ru/serega6531/packmate/pcap/FilePcapWorker.java index c37fe5c..a3c6c82 100644 --- a/src/main/java/ru/serega6531/packmate/pcap/FilePcapWorker.java +++ b/src/main/java/ru/serega6531/packmate/pcap/FilePcapWorker.java @@ -16,6 +16,7 @@ import ru.serega6531.packmate.service.SubscriptionService; import java.io.EOFException; import java.io.File; +import java.net.InetAddress; import java.net.UnknownHostException; @Slf4j @@ -27,9 +28,9 @@ public class FilePcapWorker extends AbstractPcapWorker { public FilePcapWorker(ServicesService servicesService, StreamService streamService, SubscriptionService subscriptionService, - String localIpString, + InetAddress localIp, String filename) throws UnknownHostException { - super(servicesService, streamService, localIpString); + super(servicesService, streamService, localIp); this.subscriptionService = subscriptionService; File directory = new File("pcaps"); diff --git a/src/main/java/ru/serega6531/packmate/pcap/LivePcapWorker.java b/src/main/java/ru/serega6531/packmate/pcap/LivePcapWorker.java index 719deec..99bef89 100644 --- a/src/main/java/ru/serega6531/packmate/pcap/LivePcapWorker.java +++ b/src/main/java/ru/serega6531/packmate/pcap/LivePcapWorker.java @@ -10,6 +10,7 @@ import ru.serega6531.packmate.exception.PcapInterfaceNotFoundException; import ru.serega6531.packmate.service.ServicesService; import ru.serega6531.packmate.service.StreamService; +import java.net.InetAddress; import java.net.UnknownHostException; import java.util.List; import java.util.concurrent.LinkedBlockingQueue; @@ -23,9 +24,9 @@ public class LivePcapWorker extends AbstractPcapWorker { public LivePcapWorker(ServicesService servicesService, StreamService streamService, - String localIpString, + InetAddress localIp, String interfaceName) throws PcapNativeException, UnknownHostException { - super(servicesService, streamService, localIpString); + super(servicesService, streamService, localIp); device = Pcaps.getDevByName(interfaceName); if (device == null) { diff --git a/src/main/java/ru/serega6531/packmate/properties/PackmateProperties.java b/src/main/java/ru/serega6531/packmate/properties/PackmateProperties.java new file mode 100644 index 0000000..90fafc9 --- /dev/null +++ b/src/main/java/ru/serega6531/packmate/properties/PackmateProperties.java @@ -0,0 +1,38 @@ +package ru.serega6531.packmate.properties; + + +import org.springframework.boot.context.properties.ConfigurationProperties; +import ru.serega6531.packmate.model.enums.CaptureMode; + +import java.net.InetAddress; + +@ConfigurationProperties("packmate") +public record PackmateProperties( + CaptureMode captureMode, + String interfaceName, + String pcapFile, + InetAddress localIp, + WebProperties web, + TimeoutProperties timeout, + CleanupProperties cleanup, + boolean ignoreEmptyPackets +) { + + public record WebProperties( + String accountLogin, + String accountPassword + ) {} + + public record TimeoutProperties( + int udpStreamTimeout, + int tcpStreamTimeout, + int checkInterval + ){} + + public record CleanupProperties( + boolean enabled, + int threshold, + int interval + ){} + +} diff --git a/src/main/java/ru/serega6531/packmate/service/ServicesService.java b/src/main/java/ru/serega6531/packmate/service/ServicesService.java index 358b530..2fb7358 100644 --- a/src/main/java/ru/serega6531/packmate/service/ServicesService.java +++ b/src/main/java/ru/serega6531/packmate/service/ServicesService.java @@ -1,12 +1,13 @@ package ru.serega6531.packmate.service; +import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; import org.modelmapper.ModelMapper; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import ru.serega6531.packmate.properties.PackmateProperties; import ru.serega6531.packmate.model.CtfService; import ru.serega6531.packmate.model.enums.SubscriptionMessageType; import ru.serega6531.packmate.model.pojo.ServiceCreateDto; @@ -15,10 +16,11 @@ import ru.serega6531.packmate.model.pojo.ServiceUpdateDto; import ru.serega6531.packmate.model.pojo.SubscriptionMessage; import ru.serega6531.packmate.repository.ServiceRepository; -import jakarta.annotation.PostConstruct; import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; @Service @Slf4j @@ -38,12 +40,12 @@ public class ServicesService { SubscriptionService subscriptionService, @Lazy PcapService pcapService, ModelMapper modelMapper, - @Value("${local-ip}") String localIpString) throws UnknownHostException { + PackmateProperties properties) { this.repository = repository; this.subscriptionService = subscriptionService; this.pcapService = pcapService; this.modelMapper = modelMapper; - this.localIp = InetAddress.getByName(localIpString); + this.localIp = properties.localIp(); } @PostConstruct diff --git a/src/main/java/ru/serega6531/packmate/service/StreamService.java b/src/main/java/ru/serega6531/packmate/service/StreamService.java index 2287481..5f4ad54 100644 --- a/src/main/java/ru/serega6531/packmate/service/StreamService.java +++ b/src/main/java/ru/serega6531/packmate/service/StreamService.java @@ -4,7 +4,6 @@ import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.Nullable; import org.modelmapper.ModelMapper; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -13,6 +12,7 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; +import ru.serega6531.packmate.properties.PackmateProperties; import ru.serega6531.packmate.model.CtfService; import ru.serega6531.packmate.model.FoundPattern; import ru.serega6531.packmate.model.Packet; @@ -60,7 +60,7 @@ public class StreamService { SubscriptionService subscriptionService, RsaKeysHolder keysHolder, ModelMapper modelMapper, - @Value("${ignore-empty-packets}") boolean ignoreEmptyPackets) { + PackmateProperties properties) { this.repository = repository; this.patternService = patternService; this.servicesService = servicesService; @@ -68,7 +68,7 @@ public class StreamService { this.subscriptionService = subscriptionService; this.keysHolder = keysHolder; this.modelMapper = modelMapper; - this.ignoreEmptyPackets = ignoreEmptyPackets; + this.ignoreEmptyPackets = properties.ignoreEmptyPackets(); } /** diff --git a/src/main/java/ru/serega6531/packmate/tasks/OldStreamsCleanupTask.java b/src/main/java/ru/serega6531/packmate/tasks/OldStreamsCleanupTask.java index f98a21d..957cbd8 100644 --- a/src/main/java/ru/serega6531/packmate/tasks/OldStreamsCleanupTask.java +++ b/src/main/java/ru/serega6531/packmate/tasks/OldStreamsCleanupTask.java @@ -1,31 +1,30 @@ package ru.serega6531.packmate.tasks; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; +import ru.serega6531.packmate.properties.PackmateProperties; import ru.serega6531.packmate.service.StreamService; import java.time.ZonedDateTime; -import java.time.temporal.ChronoUnit; @Component @Slf4j -@ConditionalOnExpression("${old-streams-cleanup-enabled:false} && '${capture-mode}' == 'LIVE'") +@ConditionalOnExpression("${packmate.cleanup.enabled:false} && '${packmate.capture-mode}' == 'LIVE'") public class OldStreamsCleanupTask { private final StreamService service; private final int oldStreamsThreshold; - public OldStreamsCleanupTask(StreamService service, @Value("${old-streams-threshold}") int oldStreamsThreshold) { + public OldStreamsCleanupTask(StreamService service, PackmateProperties properties) { this.service = service; - this.oldStreamsThreshold = oldStreamsThreshold; + this.oldStreamsThreshold = properties.cleanup().threshold(); } - @Scheduled(fixedDelayString = "PT${cleanup-interval}M", initialDelayString = "PT1M") + @Scheduled(fixedDelayString = "PT${packmate.cleanup.interval}M", initialDelayString = "PT1M") public void cleanup() { - ZonedDateTime before = ZonedDateTime.now().minus(oldStreamsThreshold, ChronoUnit.MINUTES); + ZonedDateTime before = ZonedDateTime.now().minusMinutes(oldStreamsThreshold); log.info("Cleaning up old non-favorite streams (before {})", before); long deleted = service.cleanupOldStreams(before); log.info("Deleted {} rows", deleted); diff --git a/src/main/java/ru/serega6531/packmate/tasks/StartupListener.java b/src/main/java/ru/serega6531/packmate/tasks/StartupListener.java index 16e923c..0a42830 100644 --- a/src/main/java/ru/serega6531/packmate/tasks/StartupListener.java +++ b/src/main/java/ru/serega6531/packmate/tasks/StartupListener.java @@ -1,10 +1,10 @@ package ru.serega6531.packmate.tasks; import org.pcap4j.core.PcapNativeException; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; +import ru.serega6531.packmate.properties.PackmateProperties; import ru.serega6531.packmate.model.enums.CaptureMode; import ru.serega6531.packmate.service.PcapService; import ru.serega6531.packmate.service.ServicesService; @@ -12,28 +12,22 @@ import ru.serega6531.packmate.service.ServicesService; @Component public class StartupListener { - @Value("${enable-capture}") - private boolean enableCapture; - - @Value("${capture-mode}") - private CaptureMode captureMode; - + private final PackmateProperties packmateProperties; private final PcapService pcapService; private final ServicesService servicesService; - public StartupListener(PcapService pcapService, ServicesService servicesService) { + public StartupListener(PcapService pcapService, ServicesService servicesService, PackmateProperties packmateProperties) { this.pcapService = pcapService; this.servicesService = servicesService; + this.packmateProperties = packmateProperties; } @EventListener(ApplicationReadyEvent.class) public void afterStartup() throws PcapNativeException { - if (enableCapture) { - servicesService.updateFilter(); + servicesService.updateFilter(); - if (captureMode == CaptureMode.LIVE) { - pcapService.start(); - } + if (packmateProperties.captureMode() == CaptureMode.LIVE) { + pcapService.start(); } } diff --git a/src/main/java/ru/serega6531/packmate/tasks/TimeoutStreamsSaver.java b/src/main/java/ru/serega6531/packmate/tasks/TimeoutStreamsSaver.java index 466074b..2befc9d 100644 --- a/src/main/java/ru/serega6531/packmate/tasks/TimeoutStreamsSaver.java +++ b/src/main/java/ru/serega6531/packmate/tasks/TimeoutStreamsSaver.java @@ -2,10 +2,10 @@ package ru.serega6531.packmate.tasks; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; +import ru.serega6531.packmate.properties.PackmateProperties; import ru.serega6531.packmate.model.enums.Protocol; import ru.serega6531.packmate.pcap.PcapWorker; @@ -13,7 +13,7 @@ import java.util.concurrent.TimeUnit; @Component @Slf4j -@ConditionalOnProperty(name = "capture-mode", havingValue = "LIVE") +@ConditionalOnProperty(name = "packmate.capture-mode", havingValue = "LIVE") public class TimeoutStreamsSaver { private final PcapWorker pcapWorker; @@ -22,14 +22,13 @@ public class TimeoutStreamsSaver { @Autowired public TimeoutStreamsSaver(PcapWorker pcapWorker, - @Value("${udp-stream-timeout}") int udpStreamTimeout, - @Value("${tcp-stream-timeout}") int tcpStreamTimeout) { + PackmateProperties properties) { this.pcapWorker = pcapWorker; - this.udpStreamTimeoutMillis = TimeUnit.SECONDS.toMillis(udpStreamTimeout); - this.tcpStreamTimeoutMillis = TimeUnit.SECONDS.toMillis(tcpStreamTimeout); + this.udpStreamTimeoutMillis = TimeUnit.SECONDS.toMillis(properties.timeout().udpStreamTimeout()); + this.tcpStreamTimeoutMillis = TimeUnit.SECONDS.toMillis(properties.timeout().tcpStreamTimeout()); } - @Scheduled(fixedRateString = "PT${timeout-stream-check-interval}S", initialDelayString = "PT${timeout-stream-check-interval}S") + @Scheduled(fixedRateString = "PT${packmate.timeout.check-interval}S", initialDelayString = "PT${packmate.timeout.check-interval}S") public void saveStreams() { int streamsClosed = pcapWorker.closeTimeoutStreams(Protocol.UDP, udpStreamTimeoutMillis); if (streamsClosed > 0) { diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index a7e663a..274a3a3 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,6 @@ spring: datasource: - url: "jdbc:postgresql://localhost/packmate" + url: "jdbc:postgresql://localhost:5432/packmate" username: "packmate" password: "123456" driver-class-name: org.postgresql.Driver @@ -14,18 +14,25 @@ spring: order_inserts: true database-platform: org.hibernate.dialect.PostgreSQLDialect +server: + compression: + enabled: true + min-response-size: 1KB -enable-capture: true -capture-mode: LIVE # LIVE, FILE, VIEW -interface-name: enp0s31f6 -pcap-file: file.pcap -local-ip: "192.168.0.125" -account-login: BinaryBears -account-password: 123456 -udp-stream-timeout: 20 # seconds -tcp-stream-timeout: 40 # seconds -timeout-stream-check-interval: 10 # seconds -old-streams-cleanup-enabled: true -old-streams-threshold: 240 # minutes -cleanup-interval: 5 # minutes -ignore-empty-packets: true \ No newline at end of file +packmate: + capture-mode: LIVE # LIVE, FILE, VIEW + interface-name: enp0s31f6 + pcap-file: file.pcap + local-ip: "192.168.0.125" + web: + account-login: BinaryBears + account-password: 123456 + timeout: + udp-stream-timeout: 20 # seconds + tcp-stream-timeout: 40 # seconds + check-interval: 10 # seconds + cleanup: + enabled: true + threshold: 240 # minutes + interval: 5 # minutes + ignore-empty-packets: true \ No newline at end of file