diff --git a/build.gradle b/build.gradle
index b88f4542cc05422dcee3e5491eb9d93ed75f7ec7..1b29e4ade60f1ece03c8e7680004ea772cfc1ef3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -30,12 +30,19 @@ dependencies {
     compileOnly 'org.projectlombok:lombok'
     runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
     runtimeOnly 'com.mysql:mysql-connector-j'
-    implementation 'org.pacesys:openstack4j:3.1.0'
     annotationProcessor 'org.projectlombok:lombok'
     testImplementation 'org.springframework.boot:spring-boot-starter-test'
     testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
+    implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
+    annotationProcessor "jakarta.annotation:jakarta.annotation-api"
+    annotationProcessor "jakarta.persistence:jakarta.persistence-api"
+    annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
+
 }
 
 tasks.named('test') {
     useJUnitPlatform()
 }
+clean {
+    delete file('src/main/generated')
+}
\ No newline at end of file
diff --git a/src/main/java/com/aolda/itda/aspect/ForwardingLogAspect.java b/src/main/java/com/aolda/itda/aspect/ForwardingLogAspect.java
new file mode 100644
index 0000000000000000000000000000000000000000..f515ab60257a9ff15d65d91080ed3fb94967d53a
--- /dev/null
+++ b/src/main/java/com/aolda/itda/aspect/ForwardingLogAspect.java
@@ -0,0 +1,154 @@
+package com.aolda.itda.aspect;
+
+import com.aolda.itda.dto.forwarding.ForwardingDTO;
+import com.aolda.itda.entity.forwarding.Forwarding;
+import com.aolda.itda.entity.log.Action;
+import com.aolda.itda.entity.log.Log;
+import com.aolda.itda.entity.log.ObjectType;
+import com.aolda.itda.entity.user.User;
+import com.aolda.itda.exception.CustomException;
+import com.aolda.itda.exception.ErrorCode;
+import com.aolda.itda.repository.certificate.CertificateRepository;
+import com.aolda.itda.repository.forwarding.ForwardingRepository;
+import com.aolda.itda.repository.log.LogRepository;
+import com.aolda.itda.repository.routing.RoutingRepository;
+import com.aolda.itda.repository.user.UserRepository;
+import com.aolda.itda.service.AuthService;
+import jakarta.persistence.EntityManager;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import java.util.Map;
+import java.util.Objects;
+
+@Aspect
+@Component
+@RequiredArgsConstructor
+public class ForwardingLogAspect {
+
+    private final ForwardingRepository forwardingRepository;
+    private final LogRepository logRepository;
+    private final EntityManager entityManager;
+    private final UserRepository userRepository;
+
+    /* Create 로깅 */
+    @AfterReturning(pointcut = "execution(* com.aolda.itda.service.forwarding.*Service.*create*(..))"
+    , returning = "result")
+    public void createLogging(JoinPoint joinPoint, ForwardingDTO result) {
+
+        /* 사용자 조회 */
+        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
+        Map<String, String> tmp = (Map<String, String>) request.getSession().getAttribute("user");
+        User user = userRepository.findByKeystoneId(tmp.get("id")).orElseThrow(
+                () -> new CustomException(ErrorCode.NOT_FOUND_USER)
+        );
+
+        /* 생성된 엔티티 조회 */
+        Forwarding forwarding = forwardingRepository.findByForwardingIdAndIsDeleted(result.getId(), false).orElse(null);
+
+        /* 로그 메세지 작성 */
+        String description = "name: " + forwarding.getName() + "\n"
+                + "serverPort: " + forwarding.getServerPort() + "\n"
+                + "instanceIp: " + forwarding.getInstanceIp() + "\n"
+                + "instancePort: " + forwarding.getInstancePort();
+
+        /* 로그 엔티티 저장 */
+        logRepository.save(Log.builder()
+                .user(user)
+                .objectType(ObjectType.FORWARDING)
+                .objectId(forwarding.getForwardingId())
+                .action(Action.UPDATE)
+                .projectId(forwarding.getProjectId())
+                .description(description)
+                .build());
+    }
+
+    /* Delete 로깅 */
+    @AfterReturning(pointcut = "execution(* com.aolda.itda.service.forwarding.*Service.*delete*(..))")
+    public void deleteLogging(JoinPoint joinPoint) {
+        
+        /* 사용자 조회 */
+        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
+        Map<String, String> tmp = (Map<String, String>) request.getSession().getAttribute("user");
+        User user = userRepository.findByKeystoneId(tmp.get("id")).orElseThrow(
+                () -> new CustomException(ErrorCode.NOT_FOUND_USER)
+        );
+
+        /* 삭제된 엔티티 조회 */
+        Object[] args = joinPoint.getArgs();
+
+        Long id = (Long) args[0];
+        Forwarding forwarding = forwardingRepository.findByForwardingIdAndIsDeleted(id, true).orElse(null);
+
+        /* 로그 메세지 작성 */
+        String description = "name: " + forwarding.getName() + "\n"
+                + "serverPort: " + forwarding.getServerPort() + "\n"
+                + "instanceIp: " + forwarding.getInstanceIp() + "\n"
+                + "instancePort: " + forwarding.getInstancePort();
+
+        /* 로그 엔티티 저장 */
+        logRepository.save(Log.builder()
+                .user(user)
+                .objectType(ObjectType.FORWARDING)
+                .objectId(forwarding.getForwardingId())
+                .action(Action.UPDATE)
+                .projectId(forwarding.getProjectId())
+                .description(description)
+                .build());
+    }
+
+    /* Update(edit) 로깅 */
+    @Around("execution(* com.aolda.itda.service.forwarding.*Service.*edit*(..))")
+    public Object editLogging(ProceedingJoinPoint joinPoint) throws Throwable {
+        
+        /* 사용자 조회 */
+        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
+        Map<String, String> tmp = (Map<String, String>) request.getSession().getAttribute("user");
+        User user = userRepository.findByKeystoneId(tmp.get("id")).orElseThrow(
+                () -> new CustomException(ErrorCode.NOT_FOUND_USER)
+        );
+
+        /* 변경 전 엔티티 조회 */
+        Object[] args = joinPoint.getArgs();
+
+        Long id = (Long) args[0];
+        Forwarding old = forwardingRepository.findByForwardingIdAndIsDeleted(id, false).orElse(null);
+        if (old != null) {
+            entityManager.detach(old);
+        }
+        
+        /* 메소드 진행 */
+        Object result = joinPoint.proceed();
+
+        /* 변경 후 엔티티 조회*/
+        Forwarding newObj = forwardingRepository.findByForwardingIdAndIsDeleted(id, false).orElse(null);
+        
+        /* 로그 메세지 작성 */
+        String description = "name: " + old.getName() + (old.getName().equals(newObj.getName()) ? "" : (" -> " + newObj.getName())) + "\n"
+                + "serverPort: " + old.getServerPort() + (old.getServerPort().equals(newObj.getServerPort()) ? "" : (" -> " + newObj.getServerPort())) + "\n"
+                + "instanceIp: " + (old.getInstanceIp().equals(newObj.getInstanceIp()) ? "" : (" -> " + newObj.getInstanceIp())) + "\n"
+                + "instancePort: " + (old.getInstancePort().equals(newObj.getInstancePort()) ? "" : (" -> " + newObj.getInstancePort()));
+
+        /* 로그 엔티티 저장 */
+        logRepository.save(Log.builder()
+                .user(user)
+                .objectType(ObjectType.FORWARDING)
+                .objectId(newObj.getForwardingId())
+                .action(Action.UPDATE)
+                .projectId(newObj.getProjectId())
+                .description(description)
+                .build());
+        return result;
+    }
+
+
+
+}
diff --git a/src/main/java/com/aolda/itda/aspect/RoutingLogAspect.java b/src/main/java/com/aolda/itda/aspect/RoutingLogAspect.java
new file mode 100644
index 0000000000000000000000000000000000000000..c8b052a7d260dc4e27c36b978f76e2375a478a2e
--- /dev/null
+++ b/src/main/java/com/aolda/itda/aspect/RoutingLogAspect.java
@@ -0,0 +1,157 @@
+package com.aolda.itda.aspect;
+
+import com.aolda.itda.dto.forwarding.ForwardingDTO;
+import com.aolda.itda.dto.routing.RoutingDTO;
+import com.aolda.itda.entity.forwarding.Forwarding;
+import com.aolda.itda.entity.log.Action;
+import com.aolda.itda.entity.log.Log;
+import com.aolda.itda.entity.log.ObjectType;
+import com.aolda.itda.entity.routing.Routing;
+import com.aolda.itda.entity.user.User;
+import com.aolda.itda.exception.CustomException;
+import com.aolda.itda.exception.ErrorCode;
+import com.aolda.itda.repository.forwarding.ForwardingRepository;
+import com.aolda.itda.repository.log.LogRepository;
+import com.aolda.itda.repository.routing.RoutingRepository;
+import com.aolda.itda.repository.user.UserRepository;
+import jakarta.persistence.EntityManager;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import java.util.Map;
+import java.util.Objects;
+
+@Aspect
+@Component
+@RequiredArgsConstructor
+public class RoutingLogAspect {
+
+    private final RoutingRepository routingRepository;
+    private final UserRepository userRepository;
+    private final LogRepository logRepository;
+    private final EntityManager entityManager;
+
+    /* Create 로깅 */
+    @AfterReturning(pointcut = "execution(* com.aolda.itda.service.routing.*Service.*create*(..))"
+            , returning = "result")
+    public void createLogging(JoinPoint joinPoint, RoutingDTO result) {
+
+        /* 사용자 조회 */
+        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
+        Map<String, String> tmp = (Map<String, String>) request.getSession().getAttribute("user");
+        User user = userRepository.findByKeystoneId(tmp.get("id")).orElseThrow(
+                () -> new CustomException(ErrorCode.NOT_FOUND_USER)
+        );
+
+        /* 생성된 엔티티 조회 */
+        Routing routing = routingRepository.findByRoutingIdAndIsDeleted(result.getId(), false).orElse(null);
+
+        /* 로그 메세지 작성 */
+        String description = "name: " + routing.getName() + "\n"
+                + "domain: " + routing.getDomain() + "\n"
+                + "ip: " + routing.getInstanceIp() + "\n"
+                + "ip: " + routing.getInstancePort() + "\n"
+                + "certificateId: " + routing.getCertificate().getCertificateId() + "\n"
+                + "caching: " + routing.getCaching() + "\n";
+
+        /* 로그 엔티티 저장 */
+        logRepository.save(Log.builder()
+                .user(user)
+                .objectType(ObjectType.FORWARDING)
+                .objectId(routing.getRoutingId())
+                .action(Action.UPDATE)
+                .projectId(routing.getProjectId())
+                .description(description)
+                .build());
+    }
+
+    /* Delete 로깅 */
+    @AfterReturning(pointcut = "execution(* com.aolda.itda.service.routing.*Service.*delete*(..))")
+    public void deleteLogging(JoinPoint joinPoint) {
+
+        /* 사용자 조회 */
+        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
+        Map<String, String> tmp = (Map<String, String>) request.getSession().getAttribute("user");
+        User user = userRepository.findByKeystoneId(tmp.get("id")).orElseThrow(
+                () -> new CustomException(ErrorCode.NOT_FOUND_USER)
+        );
+
+        /* 삭제된 엔티티 조회 */
+        Object[] args = joinPoint.getArgs();
+
+        Long id = (Long) args[0];
+        Routing routing = routingRepository.findByRoutingIdAndIsDeleted(id, true).orElse(null);
+
+        /* 로그 메세지 작성 */
+        String description = "name: " + routing.getName() + "\n"
+                + "domain: " + routing.getDomain() + "\n"
+                + "ip: " + routing.getInstanceIp() + "\n"
+                + "ip: " + routing.getInstancePort() + "\n"
+                + "certificateId: " + routing.getCertificate().getCertificateId() + "\n"
+                + "caching: " + routing.getCaching() + "\n";
+
+        /* 로그 엔티티 저장 */
+        logRepository.save(Log.builder()
+                .user(user)
+                .objectType(ObjectType.FORWARDING)
+                .objectId(routing.getRoutingId())
+                .action(Action.UPDATE)
+                .projectId(routing.getProjectId())
+                .description(description)
+                .build());
+    }
+
+    /* Update(edit) 로깅 */
+    @Around("execution(* com.aolda.itda.service.forwarding.*Service.*edit*(..))")
+    public Object editLogging(ProceedingJoinPoint joinPoint) throws Throwable {
+
+        /* 사용자 조회 */
+        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
+        Map<String, String> tmp = (Map<String, String>) request.getSession().getAttribute("user");
+        User user = userRepository.findByKeystoneId(tmp.get("id")).orElseThrow(
+                () -> new CustomException(ErrorCode.NOT_FOUND_USER)
+        );
+
+        /* 변경 전 엔티티 조회 */
+        Object[] args = joinPoint.getArgs();
+
+        Long id = (Long) args[0];
+        Routing old = routingRepository.findByRoutingIdAndIsDeleted(id, false).orElse(null);
+        if (old != null) {
+            entityManager.detach(old);
+        }
+
+        /* 메소드 진행 */
+        Object result = joinPoint.proceed();
+
+        /* 변경 후 엔티티 조회 */
+        Routing newObj = routingRepository.findByRoutingIdAndIsDeleted(id, false).orElse(null);
+
+        /* 로그 메세지 작성 */
+        String description = "name: " + old.getName() + (old.getName().equals(newObj.getName()) ? "" : (" -> " + newObj.getName())) + "\n"
+                + "domain: " + old.getDomain() + (old.getDomain().equals(newObj.getDomain()) ? "" : (" -> " + newObj.getDomain())) + "\n"
+                + "ip: " + (old.getInstanceIp().equals(newObj.getInstanceIp()) ? "" : (" -> " + newObj.getInstanceIp())) + "\n"
+                + "port: " + (old.getInstancePort().equals(newObj.getInstancePort()) ? "" : (" -> " + newObj.getInstancePort())) + "\n"
+                + "certificateId: " + (old.getCertificate().getCertificateId() == newObj.getCertificate().getCertificateId() ? "" : (" -> " + newObj.getCertificate().getCertificateId()))
+                + "certificateId: " + (old.getCaching() == newObj.getCaching() ? "" : (" -> " + newObj.getCaching()));
+
+        /* 로그 엔티티 저장 */
+        logRepository.save(Log.builder()
+                .user(user)
+                .objectType(ObjectType.FORWARDING)
+                .objectId(newObj.getRoutingId())
+                .action(Action.UPDATE)
+                .projectId(newObj.getProjectId())
+                .description(description)
+                .build());
+        return result;
+    }
+}
diff --git a/src/main/java/com/aolda/itda/config/AuthInterceptor.java b/src/main/java/com/aolda/itda/config/AuthInterceptor.java
index 83c38212a4b0692ddd12039b3b027f3708d85a13..3a95f8a4e329d27457a75d18fac600f6fe84a836 100644
--- a/src/main/java/com/aolda/itda/config/AuthInterceptor.java
+++ b/src/main/java/com/aolda/itda/config/AuthInterceptor.java
@@ -1,10 +1,9 @@
 package com.aolda.itda.config;
 
-import com.aolda.itda.dto.auth.ProjectIdAndNameDTO;
+import com.aolda.itda.dto.auth.IdAndNameDTO;
 import com.aolda.itda.exception.CustomException;
 import com.aolda.itda.exception.ErrorCode;
 import com.aolda.itda.service.AuthService;
-import com.fasterxml.jackson.core.JsonProcessingException;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import lombok.RequiredArgsConstructor;
@@ -14,7 +13,6 @@ import org.springframework.web.servlet.HandlerInterceptor;
 
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 
 @RequiredArgsConstructor
 @Component
@@ -59,9 +57,10 @@ public class AuthInterceptor implements HandlerInterceptor {
 
         /* 프로젝트 리스트 조회 */
         List<String> projects = authService.getProjectsWithUser(Map.of("id", userId, "token", token))
-                        .stream().map(ProjectIdAndNameDTO::getId)
+                        .stream().map(IdAndNameDTO::getId)
                         .toList();
         request.setAttribute("projects", projects);
+        request.setAttribute("user", Map.of("id", userId, "token", token));
         return true;
 
     }
diff --git a/src/main/java/com/aolda/itda/config/WebConfig.java b/src/main/java/com/aolda/itda/config/WebConfig.java
index 71e134bebee94ab01c47d0a032e6026d9929b62b..e3893aeecd8b181adc3bc069fbb7724fef9c38ab 100644
--- a/src/main/java/com/aolda/itda/config/WebConfig.java
+++ b/src/main/java/com/aolda/itda/config/WebConfig.java
@@ -1,6 +1,9 @@
 package com.aolda.itda.config;
 
+import com.querydsl.jpa.impl.JPAQueryFactory;
+import jakarta.persistence.EntityManager;
 import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.web.servlet.config.annotation.CorsRegistry;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
@@ -25,10 +28,15 @@ public class WebConfig implements WebMvcConfigurer {
 
     @Override
     public void addInterceptors(InterceptorRegistry registry) {
-        String[] excludeAuth = {"/error", "/api/auth/*", "/api/*" };
+        String[] excludeAuth = {"/error", "/api/auth/*" };
 
         registry.addInterceptor(authInterceptor)
                 .addPathPatterns("/**")
                 .excludePathPatterns(excludeAuth);
     }
+
+    @Bean
+    public JPAQueryFactory jpaQueryFactory(EntityManager em) {
+        return new JPAQueryFactory(em);
+    }
 }
diff --git a/src/main/java/com/aolda/itda/controller/log/LogController.java b/src/main/java/com/aolda/itda/controller/log/LogController.java
new file mode 100644
index 0000000000000000000000000000000000000000..0d4bfcf7bedf91d5fc7d1fbca6f4d68e6a5e48e8
--- /dev/null
+++ b/src/main/java/com/aolda/itda/controller/log/LogController.java
@@ -0,0 +1,41 @@
+package com.aolda.itda.controller.log;
+
+import com.aolda.itda.service.log.LogService;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.web.PageableDefault;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/api")
+@RequiredArgsConstructor
+public class LogController {
+
+    private final LogService logService;
+
+    @GetMapping("/log")
+    public ResponseEntity<Object> view(@RequestParam Long logId, HttpServletRequest request) {
+        return ResponseEntity.ok(logService.getLog(logId, (List<String>) request.getAttribute("projects")));
+    }
+
+    @GetMapping("/logs")
+    public ResponseEntity<Object> lists(@RequestParam(required = false) String projectId
+                                        ,@RequestParam(required = false) String type
+                                        ,@RequestParam(required = false) String username
+                                        ,@RequestParam(required = false) String action
+                                        ,@RequestParam(defaultValue = "false") boolean isASC
+                                        ,@PageableDefault(size = 10) Pageable pageable
+                                        ,HttpServletRequest request) {
+        return ResponseEntity.ok(logService.getLogs(projectId, type, username, action, isASC, pageable,
+                (Map<String, String>) request.getAttribute("user")));
+    }
+
+}
diff --git a/src/main/java/com/aolda/itda/dto/PageResp.java b/src/main/java/com/aolda/itda/dto/PageResp.java
index 49a2a6cdbacdee106e68588dc7b22cb43bb70fa7..7079600bbabe8b47e3e4c57f5267e8b287c8a473 100644
--- a/src/main/java/com/aolda/itda/dto/PageResp.java
+++ b/src/main/java/com/aolda/itda/dto/PageResp.java
@@ -15,7 +15,7 @@ import java.util.List;
 @JsonInclude(JsonInclude.Include.NON_NULL)
 public class PageResp<T> {
     private Integer totalPages;
-    private Integer totalElements;
+    private Long totalElements;
     private Integer size;
     private List<T> contents;
     private Boolean first;
diff --git a/src/main/java/com/aolda/itda/dto/auth/IdAndNameDTO.java b/src/main/java/com/aolda/itda/dto/auth/IdAndNameDTO.java
new file mode 100644
index 0000000000000000000000000000000000000000..5918105381265b66446aa2d221657508e177fb58
--- /dev/null
+++ b/src/main/java/com/aolda/itda/dto/auth/IdAndNameDTO.java
@@ -0,0 +1,24 @@
+package com.aolda.itda.dto.auth;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.querydsl.core.annotations.QueryProjection;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Getter
+@NoArgsConstructor
+@Builder
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class IdAndNameDTO {
+
+    private String id;
+    private String name;
+
+    @QueryProjection
+    public IdAndNameDTO(String id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+}
diff --git a/src/main/java/com/aolda/itda/dto/auth/LoginResponseDTO.java b/src/main/java/com/aolda/itda/dto/auth/LoginResponseDTO.java
index 33ba32fd358f5ab1fffecbe0965cc8921a88bbb2..a647b05835b9614cf21b1b8340a31b256fade9bc 100644
--- a/src/main/java/com/aolda/itda/dto/auth/LoginResponseDTO.java
+++ b/src/main/java/com/aolda/itda/dto/auth/LoginResponseDTO.java
@@ -13,5 +13,5 @@ import java.util.List;
 @Builder
 public class LoginResponseDTO {
     private Boolean isAdmin;
-    private List<ProjectIdAndNameDTO> projects;
+    private List<IdAndNameDTO> projects;
 }
diff --git a/src/main/java/com/aolda/itda/dto/auth/ProjectIdAndNameDTO.java b/src/main/java/com/aolda/itda/dto/auth/ProjectIdAndNameDTO.java
deleted file mode 100644
index 1ca894d2bf9b9cd5f29244ac95e7c4950daec174..0000000000000000000000000000000000000000
--- a/src/main/java/com/aolda/itda/dto/auth/ProjectIdAndNameDTO.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.aolda.itda.dto.auth;
-
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-
-@Getter
-@NoArgsConstructor
-@AllArgsConstructor
-@Builder
-public class ProjectIdAndNameDTO {
-
-    private String id;
-    private String name;
-}
diff --git a/src/main/java/com/aolda/itda/dto/log/LogDTO.java b/src/main/java/com/aolda/itda/dto/log/LogDTO.java
new file mode 100644
index 0000000000000000000000000000000000000000..589545518431c85d093ca695b3cb97778fb9bac0
--- /dev/null
+++ b/src/main/java/com/aolda/itda/dto/log/LogDTO.java
@@ -0,0 +1,38 @@
+package com.aolda.itda.dto.log;
+
+import com.aolda.itda.dto.auth.IdAndNameDTO;
+import com.aolda.itda.entity.log.Action;
+import com.aolda.itda.entity.log.ObjectType;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.querydsl.core.annotations.QueryProjection;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+@Data
+@NoArgsConstructor
+@Builder
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class LogDTO {
+    private Long id;
+    private IdAndNameDTO user;
+    private Action action;
+    private ObjectType type;
+    private Long objectId;
+    private String description;
+    private LocalDateTime createdAt;
+
+    @QueryProjection
+    public LogDTO(Long id, IdAndNameDTO user, Action action, ObjectType type, Long objectId, String description, LocalDateTime createdAt) {
+        this.id = id;
+        this.user = user;
+        this.action = action;
+        this.type = type;
+        this.objectId = objectId;
+        this.description = description;
+        this.createdAt = createdAt;
+    }
+}
diff --git a/src/main/java/com/aolda/itda/entity/BaseTimeEntity.java b/src/main/java/com/aolda/itda/entity/BaseTimeEntity.java
index 4460eb7b0c8c1401e10dcc56a34a09e81beca59a..6cfa1fde46f85bae5cf6c3ae7b2e543002db0ad9 100644
--- a/src/main/java/com/aolda/itda/entity/BaseTimeEntity.java
+++ b/src/main/java/com/aolda/itda/entity/BaseTimeEntity.java
@@ -1,5 +1,6 @@
 package com.aolda.itda.entity;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import jakarta.persistence.Column;
 import jakarta.persistence.EntityListeners;
 import jakarta.persistence.MappedSuperclass;
@@ -17,10 +18,12 @@ public abstract class BaseTimeEntity {
 
     @CreatedDate
     @Column(updatable = false)
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
     private LocalDateTime createdAt;
 
     @LastModifiedDate
     @Column(name = "updated_at")
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
     private LocalDateTime updatedAt;
 
 }
diff --git a/src/main/java/com/aolda/itda/entity/forwarding/Forwarding.java b/src/main/java/com/aolda/itda/entity/forwarding/Forwarding.java
index b0c8d34715c26ce8334e6037ea97c65329761c72..86f46b767f85217fd224a55e4951ccafe08e2f4c 100644
--- a/src/main/java/com/aolda/itda/entity/forwarding/Forwarding.java
+++ b/src/main/java/com/aolda/itda/entity/forwarding/Forwarding.java
@@ -4,10 +4,7 @@ import com.aolda.itda.dto.forwarding.ForwardingDTO;
 import com.aolda.itda.entity.BaseTimeEntity;
 import com.aolda.itda.entity.user.User;
 import jakarta.persistence.*;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
+import lombok.*;
 
 @Entity
 @Table(name = "forwarding")
@@ -15,6 +12,7 @@ import lombok.NoArgsConstructor;
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor
+@ToString
 public class Forwarding extends BaseTimeEntity {
 
     @Id
@@ -40,6 +38,18 @@ public class Forwarding extends BaseTimeEntity {
 
     private String name;
 
+    public Forwarding(Forwarding forwarding) {
+        this.forwardingId = forwarding.getForwardingId();
+        this.user = forwarding.getUser();
+        this.projectId = forwarding.getProjectId();
+        this.serverIp = forwarding.getServerIp();
+        this.serverPort = forwarding.getServerPort();
+        this.instanceIp = forwarding.getInstanceIp();
+        this.instancePort = forwarding.getInstancePort();
+        this.isDeleted = forwarding.getIsDeleted();
+        this.name = forwarding.getName();
+    }
+
     public ForwardingDTO toForwardingDTO() {
         return ForwardingDTO.builder()
                 .id(forwardingId)
diff --git a/src/main/java/com/aolda/itda/entity/log/Log.java b/src/main/java/com/aolda/itda/entity/log/Log.java
index fa78a6677f3cbb66322056a83dfd2a404eb5435c..373a836541823c018c770b131683760cd6a4b47a 100644
--- a/src/main/java/com/aolda/itda/entity/log/Log.java
+++ b/src/main/java/com/aolda/itda/entity/log/Log.java
@@ -1,5 +1,7 @@
 package com.aolda.itda.entity.log;
 
+import com.aolda.itda.dto.auth.IdAndNameDTO;
+import com.aolda.itda.dto.log.LogDTO;
 import com.aolda.itda.entity.BaseTimeEntity;
 import com.aolda.itda.entity.user.User;
 import jakarta.persistence.*;
@@ -37,4 +39,16 @@ public class Log extends BaseTimeEntity {
 
     private String description;
 
+    public LogDTO toLogDTO() {
+        return LogDTO.builder()
+                .id(logId)
+                .user(IdAndNameDTO.builder().id(user.getKeystoneId()).name(user.getKeystoneUsername()).build())
+                .action(action)
+                .type(objectType)
+                .objectId(objectId)
+                .description(description)
+                .createdAt(getCreatedAt())
+                .build();
+    }
+
 }
diff --git a/src/main/java/com/aolda/itda/exception/ErrorCode.java b/src/main/java/com/aolda/itda/exception/ErrorCode.java
index 6eea5fb80b24a23bab78c4c0ee5676feac05bae4..3e4b0be8af87fa6ad85462e6a86fb52d6c295b2d 100644
--- a/src/main/java/com/aolda/itda/exception/ErrorCode.java
+++ b/src/main/java/com/aolda/itda/exception/ErrorCode.java
@@ -10,6 +10,7 @@ public enum ErrorCode {
 
     // User
     INVALID_USER_INFO(HttpStatus.BAD_REQUEST, "잘못된 회원 정보입니다"),
+    NOT_FOUND_USER(HttpStatus.BAD_REQUEST, "존재하지 않는 사용자입니다"),
     UNAUTHORIZED_USER(HttpStatus.BAD_REQUEST, "권한이 없는 사용자입니다"),
 
     // Token
@@ -20,6 +21,9 @@ public enum ErrorCode {
 
     // Routing
     NOT_FOUND_ROUTING(HttpStatus.BAD_REQUEST, "라우팅 파일이 존재하지 않습니다"),
+    
+    // Routing
+    NOT_FOUND_LOG(HttpStatus.BAD_REQUEST, "로그가 존재하지 않습니다"),
 
     // Certificate
     NOT_FOUND_CERTIFICATE(HttpStatus.BAD_REQUEST, "SSL 인증서가 존재하지 않습니다"),
diff --git a/src/main/java/com/aolda/itda/repository/log/LogQueryDSL.java b/src/main/java/com/aolda/itda/repository/log/LogQueryDSL.java
new file mode 100644
index 0000000000000000000000000000000000000000..3ec962ba71fe611200dd83fa8fa2da04b0e38ef5
--- /dev/null
+++ b/src/main/java/com/aolda/itda/repository/log/LogQueryDSL.java
@@ -0,0 +1,104 @@
+package com.aolda.itda.repository.log;
+
+import com.aolda.itda.dto.PageResp;
+import com.aolda.itda.dto.auth.QIdAndNameDTO;
+import com.aolda.itda.dto.log.LogDTO;
+import com.aolda.itda.dto.log.QLogDTO;
+import com.aolda.itda.entity.log.Action;
+import com.aolda.itda.entity.log.ObjectType;
+import com.querydsl.core.BooleanBuilder;
+import com.querydsl.jpa.impl.JPAQuery;
+import com.querydsl.jpa.impl.JPAQueryFactory;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.support.PageableExecutionUtils;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+import static com.aolda.itda.entity.log.QLog.*;
+import static com.aolda.itda.entity.user.QUser.*;
+
+@Repository
+@RequiredArgsConstructor
+public class LogQueryDSL {
+
+    private final JPAQueryFactory jpaQueryFactory;
+
+    /* log 목록 반환 */
+    public PageResp<LogDTO> getLogs(String projectId, String type,
+                                    String username, String action, Boolean isASC, Pageable pageable) {
+
+        List<LogDTO> content = jpaQueryFactory
+                .select(new QLogDTO(
+                        log.logId,
+                        new QIdAndNameDTO(user.keystoneId, user.keystoneUsername),
+                        log.action,
+                        log.objectType,
+                        log.objectId,
+                        log.description,
+                        log.createdAt
+                )).from(log)
+                .join(log.user, user).on(log.user.eq(user))
+                .where(getFilter(projectId, type, username, action))
+                .orderBy(isASC ? log.logId.asc() : log.logId.desc())
+                .offset(pageable.getOffset())
+                .limit(pageable.getPageSize())
+                .fetch();
+
+        JPAQuery<Long> cnt = jpaQueryFactory
+                .select(log.count())
+                .from(log)
+                .where(getFilter(projectId, type, username, action));
+
+        Page<LogDTO> page = PageableExecutionUtils.getPage(content, pageable, cnt::fetchOne);
+
+        return PageResp.<LogDTO>builder()
+                .contents(page.getContent())
+                .first(page.isFirst())
+                .last(page.isLast())
+                .size(page.getSize())
+                .totalPages(page.getTotalPages())
+                .totalElements(page.getTotalElements())
+                .build();
+    }
+
+    /* Where 필터 */
+    private BooleanBuilder getFilter(String projectId, String type,
+                                     String username, String action) {
+        BooleanBuilder builder = new BooleanBuilder();
+
+        /* 프로젝트 조건 */
+        if (projectId != null) {
+            builder.and(log.projectId.eq(projectId));
+        }
+
+        /* 오브젝트 타입 조건 ( 기본 : ROUTING ) */
+        if (type.equals("certificate")) {
+            builder.and(log.objectType.eq(ObjectType.CERTIFICATE));
+        }
+        else if (type.equals("forwarding")) {
+            builder.and(log.objectType.eq(ObjectType.FORWARDING));
+        }
+        else {
+            builder.and(log.objectType.eq(ObjectType.ROUTING));
+        }
+
+        /* 사용자 ID 조건 */
+        if (username != null) {
+            builder.and(log.user.keystoneUsername.eq(username));
+        }
+
+        /* CUD 조건 */
+        if (action.equals("create")) {
+            builder.and(log.action.eq(Action.CREATE));
+        } else if (action.equals("update")) {
+            builder.and(log.action.eq(Action.UPDATE));
+        } else if (action.equals("delete")) {
+            builder.and(log.action.eq(Action.DELETE));
+        }
+
+        return builder;
+    }
+}
diff --git a/src/main/java/com/aolda/itda/repository/log/LogRepository.java b/src/main/java/com/aolda/itda/repository/log/LogRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..de0a769f6b1b206f5d350aae620fa997f7763006
--- /dev/null
+++ b/src/main/java/com/aolda/itda/repository/log/LogRepository.java
@@ -0,0 +1,10 @@
+package com.aolda.itda.repository.log;
+
+import com.aolda.itda.entity.log.Log;
+import com.aolda.itda.entity.routing.Routing;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+public interface LogRepository extends JpaRepository<Log, Long> {
+}
diff --git a/src/main/java/com/aolda/itda/repository/user/UserRepository.java b/src/main/java/com/aolda/itda/repository/user/UserRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..44cae688e4032b6caec7482c6c6f7e3c038736e2
--- /dev/null
+++ b/src/main/java/com/aolda/itda/repository/user/UserRepository.java
@@ -0,0 +1,11 @@
+package com.aolda.itda.repository.user;
+
+import com.aolda.itda.entity.user.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+public interface UserRepository extends JpaRepository<User, Long> {
+    Optional<User> findByKeystoneId(String keystoneId);
+    Optional<User> findByKeystoneUsername(String keystoneUsername);
+}
diff --git a/src/main/java/com/aolda/itda/service/AuthService.java b/src/main/java/com/aolda/itda/service/AuthService.java
index cbc157f6b4b7f5cf9398c9095330fd4ab40c6184..be6d764295fe1cb3d913199f4da9de315fb6ec33 100644
--- a/src/main/java/com/aolda/itda/service/AuthService.java
+++ b/src/main/java/com/aolda/itda/service/AuthService.java
@@ -2,9 +2,11 @@ package com.aolda.itda.service;
 
 import com.aolda.itda.dto.auth.LoginRequestDTO;
 import com.aolda.itda.dto.auth.LoginResponseDTO;
-import com.aolda.itda.dto.auth.ProjectIdAndNameDTO;
+import com.aolda.itda.dto.auth.IdAndNameDTO;
+import com.aolda.itda.entity.user.User;
 import com.aolda.itda.exception.CustomException;
 import com.aolda.itda.exception.ErrorCode;
+import com.aolda.itda.repository.user.UserRepository;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -31,6 +33,7 @@ public class AuthService {
     private String adminPassword;
     private final RestTemplate restTemplate = new RestTemplate();
     private final ObjectMapper objectMapper = new ObjectMapper();
+    private final UserRepository userRepository;
 
     // 사용자 로그인 후 토큰 발행 및 Role 반환
     public LoginResponseDTO userLogin(HttpServletResponse response, LoginRequestDTO loginRequestDTO) throws JsonProcessingException {
@@ -44,6 +47,13 @@ public class AuthService {
             throw new CustomException(ErrorCode.INVALID_USER_INFO);
         }
 
+
+        User entity = userRepository.findByKeystoneUsername(userId).orElse(null);
+        if (entity == null) {
+            userRepository.save(User.builder().keystoneId(validateTokenAndGetUserId(token)).
+                    keystoneUsername(userId).build());
+        }
+
         response.addHeader("X-Subject-Token", systemToken != null ? systemToken : token);
         return LoginResponseDTO.builder()
                 .isAdmin(systemToken != null)
@@ -239,7 +249,7 @@ public class AuthService {
     }
 
     // 특정 사용자의 참여 프로젝트 반환
-    public List<ProjectIdAndNameDTO> getProjectsWithUser(Map<String, String> user) throws JsonProcessingException {
+    public List<IdAndNameDTO> getProjectsWithUser(Map<String, String> user) throws JsonProcessingException {
         String userId = user.get("id");
         String token = user.get("token");
         if (userId == null || token == null) {
@@ -257,12 +267,12 @@ public class AuthService {
         JsonNode node = objectMapper.readTree(res.getBody());
         ArrayNode arrayNode = (ArrayNode) node.get("projects");
 
-        List<ProjectIdAndNameDTO> lists = new ArrayList<>();
+        List<IdAndNameDTO> lists = new ArrayList<>();
 
         for (JsonNode assignment : arrayNode) {
             String projectId = assignment.path("id").asText();
             String projectName = assignment.path("name").asText();
-            lists.add(new ProjectIdAndNameDTO(projectId, projectName));
+            lists.add(new IdAndNameDTO(projectId, projectName));
         }
         return lists;
     }
@@ -284,12 +294,12 @@ public class AuthService {
     }
 
     public void validateProjectAuth(List<String> projects, String projectId) {
-        if (!projects.contains(projectId)) {
+        if (projects != null && !projects.contains(projectId)) {
             throw new CustomException(ErrorCode.UNAUTHORIZED_USER);
         }
     }
 
-    private Boolean isAdmin(Map<String, String> user) throws JsonProcessingException {
+    public Boolean isAdmin(Map<String, String> user) throws JsonProcessingException {
         String url = keystone + "/role_assignments?user.id=" + user.get("id") + "&scope.system&include_names";
         HttpHeaders headers = new HttpHeaders();
         headers.set("X-Auth-Token", user.get("token"));
diff --git a/src/main/java/com/aolda/itda/service/forwarding/ForwardingService.java b/src/main/java/com/aolda/itda/service/forwarding/ForwardingService.java
index 441090bb334842d0a0142511f87b7992f5919a9f..85c1ec3eb5450c7adae76f06f22724397f1e09f1 100644
--- a/src/main/java/com/aolda/itda/service/forwarding/ForwardingService.java
+++ b/src/main/java/com/aolda/itda/service/forwarding/ForwardingService.java
@@ -1,7 +1,6 @@
 package com.aolda.itda.service.forwarding;
 
 import com.aolda.itda.dto.PageResp;
-import com.aolda.itda.dto.auth.ProjectIdAndNameDTO;
 import com.aolda.itda.dto.forwarding.ForwardingDTO;
 import com.aolda.itda.entity.forwarding.Forwarding;
 import com.aolda.itda.exception.CustomException;
@@ -9,20 +8,14 @@ import com.aolda.itda.exception.ErrorCode;
 import com.aolda.itda.repository.forwarding.ForwardingRepository;
 import com.aolda.itda.service.AuthService;
 import com.aolda.itda.template.ForwardingTemplate;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import jakarta.servlet.http.HttpServletRequest;
 import jakarta.validation.ConstraintViolation;
 import jakarta.validation.Validation;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.client.HttpClientErrorException;
 import org.springframework.web.client.HttpServerErrorException;
-import org.springframework.web.client.RestClientException;
 import org.springframework.web.client.RestTemplate;
 
 import java.io.BufferedWriter;
@@ -34,7 +27,6 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
 import java.util.List;
-import java.util.Map;
 
 @Service
 @Transactional
@@ -71,7 +63,7 @@ public class ForwardingService {
     }
 
     /* 포트포워딩 생성 */
-    public void createForwarding(String projectId, ForwardingDTO dto) {
+    public ForwardingDTO createForwarding(String projectId, ForwardingDTO dto) {
 
         /* 입력 DTO 검증 */
         validateDTO(dto);
@@ -163,7 +155,7 @@ public class ForwardingService {
             }
             throw new CustomException(ErrorCode.FAIL_NGINX_CONF_RELOAD);
         }
-
+        return forwarding.toForwardingDTO();
     }
 
     /* 포트포워딩 정보 수정 */
diff --git a/src/main/java/com/aolda/itda/service/log/LogService.java b/src/main/java/com/aolda/itda/service/log/LogService.java
new file mode 100644
index 0000000000000000000000000000000000000000..b33cc2e4a1e923ed046bea7aaff6ddc18c345c53
--- /dev/null
+++ b/src/main/java/com/aolda/itda/service/log/LogService.java
@@ -0,0 +1,57 @@
+package com.aolda.itda.service.log;
+
+import com.aolda.itda.dto.PageResp;
+import com.aolda.itda.dto.log.LogDTO;
+import com.aolda.itda.entity.log.Log;
+import com.aolda.itda.exception.CustomException;
+import com.aolda.itda.exception.ErrorCode;
+import com.aolda.itda.repository.log.LogRepository;
+import com.aolda.itda.repository.log.LogQueryDSL;
+import com.aolda.itda.service.AuthService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Map;
+
+@Service
+@Transactional
+@RequiredArgsConstructor
+@Slf4j
+public class LogService {
+
+    private final LogRepository logRepository;
+    private final LogQueryDSL logQueryDSL;
+    private final AuthService authService;
+
+    /* CUD 로그 조회 */
+    public LogDTO getLog(Long logId, List<String> projects) {
+        Log log = logRepository.findById(logId)
+                .orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND_LOG));
+
+        /* 프로젝트 권한 검증 */
+        authService.validateProjectAuth(projects, log.getProjectId());
+
+        return log.toLogDTO();
+    }
+
+    /* CUD 로그 목록 조회 */
+    public PageResp<LogDTO> getLogs(String projectId, String type, String username, String action, Boolean isASC,
+                                    Pageable pageable, Map<String, String> user) {
+
+        if (projectId == null) {
+            try {
+                if(!authService.isAdmin(user)) throw new CustomException(ErrorCode.UNAUTHORIZED_USER);
+            }
+            catch (Exception e) {
+                throw new CustomException(ErrorCode.UNAUTHORIZED_USER);
+            }
+        }
+
+        return logQueryDSL.getLogs(projectId, type, username, action, isASC, pageable);
+    }
+
+}
diff --git a/src/main/java/com/aolda/itda/service/routing/RoutingService.java b/src/main/java/com/aolda/itda/service/routing/RoutingService.java
index eb3777b6fc26fbbd7c822894b5fed5f640202634..7b30c9127796b6dda07d65207a0bc37abbdb9b92 100644
--- a/src/main/java/com/aolda/itda/service/routing/RoutingService.java
+++ b/src/main/java/com/aolda/itda/service/routing/RoutingService.java
@@ -54,7 +54,6 @@ public class RoutingService {
 
     /* Routing 목록 조회 */
     public PageResp<RoutingDTO> getRoutings(String projectId) {
-        // project id 확인 필요
         return PageResp.<RoutingDTO>builder()
                 .contents(routingRepository.findByProjectIdAndIsDeleted(projectId, false)
                         .stream()
@@ -63,7 +62,7 @@ public class RoutingService {
     }
 
     /* Routing 생성 */
-    public void createRouting(String projectId, RoutingDTO dto) {
+    public RoutingDTO createRouting(String projectId, RoutingDTO dto) {
         /* 입력 DTO 검증 */
         validateDTO(dto);
 
@@ -157,6 +156,7 @@ public class RoutingService {
             throw new CustomException(ErrorCode.FAIL_NGINX_CONF_RELOAD);
         }
 
+        return routing.toRoutingDTO();
     }
 
     /* Routing 수정 */
@@ -167,9 +167,6 @@ public class RoutingService {
         /* 프로젝트 권한 검증 */
         authService.validateProjectAuth(projects, routing.getProjectId());
 
-        /* 입력 DTO 검증 */
-        validateDTO(dto);
-
         /* 중복 검증 */
         if (dto.getDomain() != null && routingRepository.existsByDomainAndIsDeleted(dto.getDomain(), false)) {
             throw new CustomException(ErrorCode.DUPLICATED_DOMAIN_NAME);
@@ -182,7 +179,9 @@ public class RoutingService {
 
         /* 파일 수정 */
         routing.edit(dto, certificate);
-        String content = routingTemplate.getRouting(routing.toRoutingDTO(), certificate == null ? null : certificate.formatDomain());
+        RoutingDTO tmp = routing.toRoutingDTO();
+        if (tmp.getCertificateId() == null) tmp.setCertificateId( (long) -1);
+        String content = routingTemplate.getRouting(tmp, certificate == null ? null : certificate.formatDomain());
         String confPath = "/data/nginx/proxy_host/" + routing.getRoutingId() + ".conf";
         File file = new File(confPath);
         if (!file.exists()) {