Merge branch 'feature/SUPPORT-8818_log' into develop
This commit is contained in:
commit
a3d0971f6f
4 changed files with 72 additions and 53 deletions
35
README.md
Normal file
35
README.md
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
# **av-service**
|
||||||
|
|
||||||
|
`av-service` — это сервис, взаимодействующий с Kaspersky Endpoint Security для Linux (KESL) на одной машине.
|
||||||
|
|
||||||
|
Основная задача сервиса — обеспечение защиты и анализа файлов с помощью интеграции с KESL.
|
||||||
|
Сервис использует консольные команды для выполнения операций и взаимодействия с KESL, таких как запуск задач проверки и получение результатов анализа.
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Основные функции**
|
||||||
|
- Проверка файлов на наличие угроз с использованием KESL.
|
||||||
|
- Обработка файлов через POST-запросы.
|
||||||
|
- Логирование результатов проверки.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Требования**
|
||||||
|
- **Java 17**
|
||||||
|
- **KESL** (установлен и настроен на одной машине с сервисом)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Конфигурация и запуск**
|
||||||
|
|
||||||
|
### **1. Конфигурация параметров для сервиса**
|
||||||
|
Для корректного запуска сервиса добавьте следующие параметры в файл `application.properties`:
|
||||||
|
```properties
|
||||||
|
file.upload.directory=/tmp/uploaded_files # Путь для хранения временных файлов
|
||||||
|
spring.servlet.multipart.max-file-size=10MB # Максимальный размер загружаемого файла
|
||||||
|
spring.servlet.multipart.max-request-size=10MB # Максимальный размер запроса
|
||||||
|
server.port=8080 # Порт, на котором работает сервис
|
||||||
|
```
|
||||||
|
### **2. Запуск JAR-файла с конфигурационным файлом**
|
||||||
|
```bash
|
||||||
|
java -jar app.jar --spring.config.location=file:/path/to/your/application.properties
|
||||||
|
```
|
||||||
|
|
@ -28,10 +28,15 @@ public class FileScanController {
|
||||||
@PostMapping("/scan-file")
|
@PostMapping("/scan-file")
|
||||||
public ResponseEntity<?> scanFile(@RequestPart("file") MultipartFile file) {
|
public ResponseEntity<?> scanFile(@RequestPart("file") MultipartFile file) {
|
||||||
if (file.isEmpty()) {
|
if (file.isEmpty()) {
|
||||||
|
LOGGER.warn("The uploaded file is empty or missing.");
|
||||||
return ResponseEntity.badRequest().build();
|
return ResponseEntity.badRequest().build();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ScanResult result = fileScanService.scanFile(file);
|
ScanResult result = fileScanService.scanFile(file);
|
||||||
|
LOGGER.info("Scan result for file {}: status - {}, verdicts - {}",
|
||||||
|
file.getOriginalFilename(),
|
||||||
|
result.status(),
|
||||||
|
String.join(", ", result.verdicts()));
|
||||||
return ResponseEntity.ok(result);
|
return ResponseEntity.ok(result);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
|
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
package ru.micord.av.service.service;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
import ru.micord.av.service.exception.AvException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Adel Kalimullin
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class FileManager {
|
|
||||||
@Value("${file.upload.directory}")
|
|
||||||
public String uploadDirectory;
|
|
||||||
|
|
||||||
public File saveFile(MultipartFile file) throws IOException {
|
|
||||||
Path uploadPath = Paths.get(uploadDirectory);
|
|
||||||
if (!Files.exists(uploadPath)) {
|
|
||||||
Files.createDirectories(uploadPath);
|
|
||||||
}
|
|
||||||
Path tempFile = Files.createTempFile(uploadPath, "kesl-upload-", ".tmp");
|
|
||||||
file.transferTo(tempFile.toFile());
|
|
||||||
return tempFile.toFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deleteFile(File file) {
|
|
||||||
if (file != null && file.exists()) {
|
|
||||||
try {
|
|
||||||
Files.delete(file.toPath());
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
throw new AvException("Ошибка удаления временного файла: " + file.getAbsolutePath(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -3,12 +3,18 @@ package ru.micord.av.service.service;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import ru.micord.av.service.exception.AvException;
|
import ru.micord.av.service.exception.AvException;
|
||||||
|
|
@ -19,20 +25,18 @@ import ru.micord.av.service.model.ScanResult;
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class FileScanService {
|
public class FileScanService {
|
||||||
public static String KESL_CONTROL = "kesl-control";
|
private static final String KESL_CONTROL = "kesl-control";
|
||||||
public static String KESL_SCAN = "--scan-file";
|
private static final String KESL_SCAN = "--scan-file";
|
||||||
private final FileManager fileManager;
|
private static final Logger LOGGER = LoggerFactory.getLogger(FileScanService.class);
|
||||||
|
@Value("${file.upload.directory}")
|
||||||
public FileScanService(FileManager fileManager) {
|
private String uploadDirectory;
|
||||||
this.fileManager = fileManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScanResult scanFile(MultipartFile file) {
|
public ScanResult scanFile(MultipartFile file) {
|
||||||
File tempFile = null;
|
File tempFile = null;
|
||||||
LocalDateTime startTime;
|
LocalDateTime startTime;
|
||||||
LocalDateTime stopTime;
|
LocalDateTime stopTime;
|
||||||
try {
|
try {
|
||||||
tempFile = fileManager.saveFile(file);
|
tempFile = saveFile(file);
|
||||||
startTime = LocalDateTime.now();
|
startTime = LocalDateTime.now();
|
||||||
String rawResult = runKeslScan(tempFile);
|
String rawResult = runKeslScan(tempFile);
|
||||||
stopTime = LocalDateTime.now();
|
stopTime = LocalDateTime.now();
|
||||||
|
|
@ -41,13 +45,30 @@ public class FileScanService {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
throw new AvException("Ошибка при сканировании файла: " + file.getOriginalFilename(), e);
|
throw new AvException("Error scanning file: " + file.getOriginalFilename(), e);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
fileManager.deleteFile(tempFile);
|
try {
|
||||||
|
if (tempFile != null && tempFile.exists()) {
|
||||||
|
Files.delete(tempFile.toPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
LOGGER.warn("Error deleting file: " + tempFile.getAbsolutePath(), e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private File saveFile(MultipartFile file) throws IOException {
|
||||||
|
Path uploadPath = Paths.get(uploadDirectory);
|
||||||
|
if (!Files.exists(uploadPath)) {
|
||||||
|
Files.createDirectories(uploadPath);
|
||||||
|
}
|
||||||
|
Path tempFile = Files.createTempFile(uploadPath, "kesl-upload-", ".tmp");
|
||||||
|
file.transferTo(tempFile.toFile());
|
||||||
|
return tempFile.toFile();
|
||||||
|
}
|
||||||
|
|
||||||
private String runKeslScan(File file) throws IOException, InterruptedException {
|
private String runKeslScan(File file) throws IOException, InterruptedException {
|
||||||
ProcessBuilder processBuilder = new ProcessBuilder(KESL_CONTROL, KESL_SCAN,
|
ProcessBuilder processBuilder = new ProcessBuilder(KESL_CONTROL, KESL_SCAN,
|
||||||
file.getAbsolutePath()
|
file.getAbsolutePath()
|
||||||
|
|
@ -58,7 +79,7 @@ public class FileScanService {
|
||||||
String result = new String(inputStream.readAllBytes());
|
String result = new String(inputStream.readAllBytes());
|
||||||
int exitCode = process.waitFor();
|
int exitCode = process.waitFor();
|
||||||
if (exitCode != 0 && exitCode != 72) {
|
if (exitCode != 0 && exitCode != 72) {
|
||||||
throw new AvException("Ошибка KESL, код завершения: " + exitCode);
|
throw new AvException("KESL error, exit code: " + exitCode);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue