Log4j-api.jar
Log4j-core-2.14.1.jar
JndiLookup.class
lookup 메소드
얘가 모든 일의 시작이다
•
EnvironmentLookup 클래스 이용 환경변수 출력
•
$ 표시로 jndi
package rcvdemo1;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.lookup.EnvironmentLookup;
public class envSearchExample {
private static final Logger demoLogger = LogManager.getLogger(LoggingDemoSecond.class.getName());
public static void main(String[] args) {
// EnvironmentLookup을 사용하여 환경 변수 조회
EnvironmentLookup environmentLookup = new EnvironmentLookup();
String[] envVars = {"PATH", "JAVA_HOME", "USER", "OS"};
for (String var : envVars) {
String value = environmentLookup.lookup(var);
demoLogger.info(var + " = " + value + "\n");
}
// 환경 변수 및 JNDI 리소스를 불러오기 위한 로그 메시지
String pathVariable = "${env:PATH}";
String javaHomeVariable = "${env:JAVA_HOME}";
String userVariable = "${env:USER}";
String osVariable = "${env:OS}";
demoLogger.info("PATH environment variable: " + pathVariable);
demoLogger.info("JAVA_HOME environment variable: " + javaHomeVariable);
demoLogger.info("USER environment variable: " + userVariable);
demoLogger.info("OS environment variable: " + osVariable);
demoLogger.info("This is info");
}
}
PowerShell
복사
전체 과정
•
Logger 객체 생성
•
Logger 객체는 로그 이벤트를 Appender 에게 전달
•
Appender 는 설정 파일 (log4j2.xml) 에서 확인 가능
1. Logger가 Appender에 로그 이벤트 전달
•
strategy.log
•
loggerconfig.log
•
appernder.callAppender 에서 전달받은 LogEvent를 지정된 Layout을 사용하여 포맷
•
$ 필터링 실제 구현
•
${} 포함할경우 적절한 룩업기능
•
EnvironmentLookup
•
JNDI LOOKUP
•
convertJndiName()
◦
기본 key : java:comp/env/
◦
키에 : 를 포함하면 외부서버에서 객체를 조회할 수 있음
•
JndiManager.lookup 검증 로직
◦
직접 검증
public class JndiManager {
// ...
@SuppressWarnings("unchecked")
public <T> T lookup(final String name) throws NamingException {
if (!isValidJndiName(name)) {
throw new NamingException("Invalid JNDI name: " + name);
}
return (T) this.context.lookup(name);
}
private boolean isValidJndiName(final String jndiName) {
for (Pattern pattern : ALLOWED_URL_PATTERNS) {
if (pattern.matcher(jndiName).matches()) {
return true;
}
}
return false;
}
// ...
}
Java
복사
•
허용 URL 목록 관리
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
public class JndiManager {
private static final List<Pattern> ALLOWED_URL_PATTERNS = Arrays.asList(
Pattern.compile("^ldap://trusted\\.example\\.com/.*$"),
Pattern.compile("^ldaps://trusted\\.example\\.com/.*$")
);
private final Context context;
private JndiManager(final String name, final Context context) {
super(null, name);
this.context = context;
}
// ...
/**
* Looks up a named object through this JNDI context with input validation.
*
* @param name name of the object to look up.
* @param <T> the type of the object.
* @return the named object if it could be located.
* @throws NamingException if a naming exception is encountered or input is invalid.
*/
@SuppressWarnings("unchecked")
public <T> T lookup(final String name) throws NamingException {
if (!isValidJndiName(name)) {
throw new NamingException("Invalid JNDI name: " + name);
}
return (T) this.context.lookup(name);
}
/**
* Validates the JNDI name against allowed patterns.
*
* @param jndiName the JNDI name to validate.
* @return true if the JNDI name is valid, false otherwise.
*/
private boolean isValidJndiName(final String jndiName) {
for (Pattern pattern : ALLOWED_URL_PATTERNS) {
if (pattern.matcher(jndiName).matches()) {
return true;
}
}
return false;
}
// ...
}
Java
복사