- gitlab 파이프라인에서 타 프로젝트에 소스 반영

  : 타 프로젝트 Repository 로부터 Clone을 통해서 소스를 가져온 후 그 소스에 변경 내역을 반영한 후 배포한다.

1. git clone => 수정 => git push 

 before_script:
    - git config --global user.name "${GITLAB_USER_NAME}"
    - git config --global user.email "${GITLAB_USER_EMAIL}"
    - git config --global http.sslverify "false"

 script:
    - git clone http://gitlab-ci-token:${CI_JOB_TOKEN}@my.gitlab.com/web/my_proj.git
    - cd my_proj
    - rm -rf ./src/assets/styles
    - cp -r ../src/assets/styles ./src/assets/styles
    - git add --all
    - git commit -m "Auto Source update at `date +'%Y-%m-%d %H:%M:%S'` " || true
    - git push http://gitlab-ci-token:${ACCESS_TOKEN}@my.gitlab.com/web/my_proj.git HEAD:develop || true

* 이 때 사용되는 ${CI_JOB_TOKEN} 은 Predefined Variables 이고 이 값을 통해서는 Read 권한만 가지고 있어, clone을 통해 프로젝트를 읽어 올수만 있다.

* Push 를 통해 타 프로젝트에 업데이트 하기 위해서는 권한자의 Access Token을 생성해서 Push 할 수 있다.

Access Token 생성 방법은 Gitlab Doc 을 참조한다.

- Redhat 7 에서 두개의 모니터 중에 하나가, 해상도가 낮게 설정되는 문제점

# randr | grep -w connected

HDMI-2 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 477mm x 268mm
DP-3 connected 1024x768+1920+0 (normal left inverted right x axis y axis) 0mm x 0mm

# gtf 1920 1080 60

   # 1920x1080 @ 60.00 Hz (GTF) hsync: 67.08 kHz; pclk: 172.80 MHz
  Modeline "1920x1080_60.00"  172.80  1920 2040 2248 2576  1080 1081 1084 1118  -HSync +Vsync

# xrandr --newmode "1920x1080_60.00"  172.80  1920 2040 2248 2576  1080 1081 1084 1118  -HSync +Vsync

# xrandr --addmode DP-3 "1920x1080_60.00"

 

장치-디스플레이 에서 해당 모니터의 해상도가 1920x1080 이 보인다.

 

참조.

www.superuser.com/questions/164926/why-cant-i-get-the-right-screen-resolution-in-ubuntu

#1. 목표: Python 으로 제작된 Algorithm 소스들을 일정 시간동안 Google Cloud 내에서 실행한다. 

  - 비용등의 문제로 1000건의 Algorithm을 Kubernetes 를 이용하여 동시에 실행처리한다.

#2. 이슈: 기존에 개발된 1000건의 Algorithm을 동시에 처리하기 위해 web-was 를 이용해 multi-processing 처리를 하였으나, 

데이터 건수에 따라 Kubernetes 의 Autoscaling 이 적절하게 동작하지 않는다.

#3. 분석: 동시 작업 처리에 대한 프레임웍 사용을 하지 않고, 직접 개발을 통해 진행함으로써 다양한 문제가 발생  

  a) web-was 방식으로 multi-processing 처리시에 응답시간 문제등 다양한 문제 발생 

  b) 1000건의 request 를 이미 was 에 입력되고, 그 처리를 이미 입력받은 kubernetes 는 기존 pod 의 적정 처리량을 over 하게 되고, 새로운 pod를 생성하지만 이미 모든 request는 기존 pod로 보냈기 때문에 새로운 pod는 생성 후에도 어떤 request 도 수신하지 못함.

#4. 해결방안: Dataproc, Spark, Ray 등 데이터 처리를 Parallel 하게 진행할 수 있는 프레임워크 사용.

  Spark 사용하기로 결정 ### 난 Python 도 Spark 도 이번이 처음!!! ###

#5. 해결방안에 대한 반대의견:

1.  기존 1000 여개의 Python 소스를 Spark 형식으로 변경하게 많은 일이 진행되어야 함.

  소스 변경없이 처리하기 위해 진행.

 

Spark on Kubernetes : https://spark.apache.org/docs/latest/running-on-kubernetes.html

Prerequisite

1. Cluster 설치

gcloud container clusters create spark-kube \
     --cluster-version 1.15.9-gke.24 \
     --zone us-east4-a \
     --node-locations us-east4-a,us-east4-b,us-east4-c \
     --num-nodes 2 --enable-autoscaling --min-nodes 1 --max-nodes 4

2. node pool 구성 : Algorithm 실행 메모리 사이즈등을 고려하여 구성

  a) 메모리 사이즈가 작은 경우 에러발생.

   

3. Container Repository 생성

gcr.io/{PROJECT ID}/{TAG ID}

 

4. RBAC(Role Based Access Control) : (

  - RBAC 안했을 때 아래와 같은 에러 발생

Caused by:io.fabric8.kubernetes.client.KubernetesClientException: Failure executing: GET at: https://kubernetes.default.svc/api/v1/namespaces/default/pods/spark-pi-15543??????069-driver. Message: Forbidden!Configured service account doesn't have access. Service account may have been revoked. pods "spark-pi-1554304245069-driver" is forbidden: User "system:serviceaccount:default:default" cannot get resource "pods" in API group "" in the namespace "default".

a) serviceaccount list

 kubectl get serviceaccount 

b) spark serviceaccount 생성

 kubectl create serviceaccount spark

 serviceaccount "spark" created

 kubectl create clusterrolebinding spark-role --clusterrole=edit --serviceaccount=default:spark --namespace=default

 clusterrolebinding "spark-role" created

 

5. google cloud(GKE) 사용 설정

export PROJECT_ID="{PROJECT ID}"

export ZONE="us-east4-a"

export KUBE_CLUSTER_NAME="{Cluster Name}"

 

gcloud config set project ${PROJECT_ID}

gcloud config set compute/zone ${ZONE}

gcloud container clusters get-credentials ${KUBE_CLUSTER_NAME}

 

 

1. Spark Source Download

 - Spark 버전과 package 선택 후 3. Download Spark 링크 선택 후 mirror 페이지 복사 후 실행.

버전 선택 후 Download

 

wget http://apache.tt.co.kr/spark/spark-2.4.5/spark-2.4.5-bin-hadoop2.7.tgz

Download

tar -xvf spark-2.4.5-bin-hadoop2.7.tgz

 

2. Dockerfile 수정

- PATH: kubernetes/dockerfile/spark

Dockerfile

- Dockerfile 수정 : Python Algorithm 소스 실행을 위한 라이브러리 및 소스 추가(##ADDED)

#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

FROM openjdk:8-jdk-slim

ARG spark_jars=jars
ARG img_path=kubernetes/dockerfiles
ARG k8s_tests=kubernetes/tests


##ADDED
ENV DEBIAN_FRONTEND noninteractive

##ADDED
## install necessary packages
RUN apt-get update -y && apt-get install -y python3 python3-pip python3-numpy \
                     python3-matplotlib python3-scipy python3-pandas python3-simpy

##ADDED
## set python3 as default (currently python 3.7)
RUN update-alternatives --install "/usr/bin/python" "python" "$(which python3)" 1

##ADDED
## developed python algorithm need library belows.
RUN pip3 install --upgrade six>=1.13.0
RUN pip3 install fire \
                 smart_open \
                 google-cloud-storage \
                 pandas-gbq \
                 scikit-learn==0.22.2 \
                 pyjanitor \
                 xgboost \
                 lightgbm \
                 bayesian-optimization \
                 catboost \
                 google-cloud-bigquery \
                 pandas==1.0.1 \
                 py4j 

# Before building the docker image, first build and make a Spark distribution following
# the instructions in http://spark.apache.org/docs/latest/building-spark.html.
# If this docker file is being used in the context of building your images from a Spark
# distribution, the docker build command should be invoked from the top level directory
# of the Spark distribution. E.g.:
# docker build -t spark:latest -f kubernetes/dockerfiles/spark/Dockerfile .

RUN set -ex && \
    apt-get update && \
    ln -s /lib /lib64 && \
    apt install -y bash tini libc6 libpam-modules libnss3 && \
    mkdir -p /opt/spark && \
    mkdir -p /opt/spark/work-dir && \
    touch /opt/spark/RELEASE && \
    rm /bin/sh && \
    ln -sv /bin/bash /bin/sh && \
    echo "auth required pam_wheel.so use_uid" >> /etc/pam.d/su && \
    chgrp root /etc/passwd && chmod ug+rw /etc/passwd && \
    rm -rf /var/cache/apt/*

COPY ${spark_jars} /opt/spark/jars
COPY bin /opt/spark/bin
COPY sbin /opt/spark/sbin
COPY ${img_path}/spark/entrypoint.sh /opt/
COPY examples /opt/spark/examples
COPY ${k8s_tests} /opt/spark/tests
COPY data /opt/spark/data

##ADDED
## python algorithm sources copy
COPY ml_app/parameter_data /app/
COPY ml_app/*.py /app/
COPY ml_app.zip /app/
COPY ml_app/*.json /app/
COPY ml_app/df_modeling/ /app/df_modeling/

##ADDED
# creadtial json file
ENV GOOGLE_APPLICATION_CREDENTIALS /app/service_aacount.json


ENV SPARK_HOME /opt/spark

WORKDIR /opt/spark/work-dir

ENTRYPOINT [ "/opt/entrypoint.sh" ]

 

- Python Algorithm 개발 소스 

Python Algorihtm 소스

3. Spark Python Applicatin

-  UDF(User Defined Function) 로 Function을 등록하면, Spark 처리로직으로 인식하여 Driver가 Executor 로 전달하여 실행

# -*- coding: utf-8 -*-
# Creation Date : 2020-04-15
# last Modified : 2019-04-15 
# 

from __future__ import print_function

from pyspark import SparkContext, SparkConf, SQLContext
from pyspark.sql import HiveContext

from pyspark.sql.functions import udf, col

import queue

from threading import Thread

def callpython(val):
    import main_cns
    A = val.split(' ')
    main_cns3.main(A[0], A[1], A[2], A[3], A[4], int(A[5]))
    return val + " finished"


def main():
    # Executor가 실행할 Python library를 library path 설정 
    conf = SparkConf().setAppName("main_cns") \
            .setExecutorEnv('PYTHONPATH', 'PYTHONPATH:/app/ml_app.zip') \
            .set("spark.scheduler.mode", "FAIR")
    
    # Python source 의 Entrypoint 를 path 설정.
    sc = SparkContext(conf=conf, pyFiles=['/app/main_XXX.py'])
    sc.addPyFile('/app/ml_app.zip')
    
    sqlContext = HiveContext(sc)
    sqlContext.setConf("spark.sql.hive.convertMetastoreOrc", "false")
    
    ## User Defined Function 을 이용하여 
    ## Driver 실행 코드가 Executor에 실행 가능
    sqlContext.udf.register('udf_callpython', callpython)

    def callpython_t(x):
        rdd.map(sqlContext.sql("select udf_callpython('"+x+"') ").show())
        return 1

    rdd = sc.parallelize([1,2,3], 3)
    
    que = queue.Queue()
    threads_list = list()

    lines = [line.rstrip() for line in open('/app/parameter_data')]
    
    ## Thread 처리를 이용해 Alogrithm python을 동시에 실행 
    for A in lines:
        if not A.startswith('#'):
            thread = Thread(target=lambda q, arg1: q.put(callpython_t(arg1)), args=(que, A ))
            thread.start()
            threads_list.append(thread)

    # Join all the threads
    for t in threads_list:
        t.join()

    # Check thread's return value
    while not que.empty():
        result = que.get()
        print(result) 

    sc.stop()

if __name__ == '__main__':
    main()
   

 

4. Python Source library 생성

- ml_app 폴더로 이동 후 :  zip -r ../ml_app.zip .

 

5. Docker Image Build 

- target dockerfile : kubernetes/dockerfile/spark/Dockerfile

- bin/docker-image-tool.sh 실행하여 Image 생성 후 Container Reposiotory 빌드.

bin/docker-image-tool.sh -r gcr.io/{PROJECT_ID} -t {TAG_ID} build

bin/docker-image-tool.sh -r gcr.io/{PROJECT_ID} -t {TAG_ID} push

docker image 생성

 

6. Spark Application Run  

- MASTER IP  Check :

kubectl cluster-info | grep master |awk '{print $6}'

- spark 실행

bin/spark-submit \
         --master k8s://https://{MASETR IP}\
         --deploy-mode cluster \
         --name spark-py-pi \
         --driver-cores 1000m \
         --executor-memory 4g \   
        --conf spark.executor.instances=30 \
        --conf spark.app.name=spark-pi \
        --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark  \
        --conf spark.kubernetes.container.image=gcr.io/{PROJECT_ID}/spark-py:{TAG_ID} \
        --conf spark.kubernetes.container.image.pullPolicy=Always \
        --py-files local:///app/ml_app.zip local:///app/main_spark.py

 

 

###. Unauthorized Exception ###

- 다음과 같은 에러 발생시 

Exception in thread "main" io.fabric8.kubernetes.client.KubernetesClientException: Unauthorized
at io.fabric8.kubernetes.client.dsl.internal.WatchConnectionManager$1.onFailure(WatchConnectionManager.java:206)
at okhttp3.internal.ws.RealWebSocket.failWebSocket(RealWebSocket.java:571)

 

 kubectl -n kube-system get secret

참조 : https://www.waitingforcode.com/apache-spark/setting-up-apache-spark-kubernetes-microk8s/read

* 현재 프로젝트에서 Magento Cloud pro를 사용하고 있고, Admin 계정을 부여받았다.

1. Putty, MobaXterm 등을 이용해 ssh key 생성 (검색해보면 너무 많으므로 생략)

  - SSH Public Key를 Magento 의 해당 계정에 저장한다.

  - 생성된 Public key 값을 아래와 같이 ssh-rsa 부터 끝까지 복사해서 Add a pubkey 를 누르고 key 항목에 저장한다.

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDF0Mk/RDidV4ANrqTTCufo6Qmo6PBlZpSxmqSU4p2ATatuwjYoU+/zb5/X+K2QLitHp37BMewHTwXXXXXXXXXXYNQtj9S/h+tDK4TZqyIvT/A1atf+Wdh8GzPvC/+s7mXUYwaK4N+A0cHM6TrKDj4WPnznF/jtb7SXBF35J8U4uChOZEbZx0ZYYYYYYYYYYYxWTEVX7KxC7DA7JFMGZO8SSA5VEwpEYgeyAPkj3dScAxm03RKwQZfilxXlVgl15Z06iMKFBe0jaL7E7T4LYa9hUcnURrO4gCeg4fUvuuFY/H7Kke9aQ8gonNL Imported-Openssh-Key: C:\MobaXterm_Portable_v12.4\.ssh\id_rsa

Magento 계정에 SSH Public Key 저장

2. Git Client Tool 설치

 - SmartGit(https://www.syntevo.com/smartgit/) 설치하였음.(검색해보니 무료라...)

 - 설치 후 clone

SmartGit Clone 실행

3. Git URL 설정

- Magento의 Production, Staging 등의 Git URL을 복사 후 SmartGit의 Clone 창의 Repository URL 에 입력

Git URL SSH 계정 URL Copy(아래 Clone 팝업 화면에 Paste)
Git URL SSH 계정 URL 입력

 

SSH Public Key 생성 시의 Privage Key 선택
Check Out Branch 선택(production, staging 등)

 

- 다음으로 로컬 Repository 폴더를 선택하면 Cloning 작업이 진행된다.

SmartGit 툴에 마지막에 failed 라고 메시지가 나타나지만, 정보는 잘 로드 된것으로 보인다.(데이터에 문제가 있으면, 다른 Git 툴 사용 해보시길...)

Production Git 변경사항 확인

Jenkins 2.202 version에서 maven build 시 Java8 을 이용했을 때에는 문제가 없으나, 

특정 프로젝트가 java7 기반일 때 java jdk 1.7 추가 후 빌드시에 아래와 같은 에러 발생.

 

Parsing POMs
[workspace] $ /engn001/java/jdk1.7.0_80/bin/java -cp /engn001/csvn/.jenkins/plugins/maven-plugin/WEB-INF/lib/maven31-agent-1.5.jar:/engn001/csvn/apache-maven-3.1.0/boot/plexus-classworlds-2.4.2.jar:/engn001/csvn/apache-maven-3.1.0/conf/logging jenkins.maven3.agent.Maven31Main /engn001/csvn/apache-maven-3.1.0 /engn001/csvn/apache-tomcat-8.0.9/webapps/jenkins/WEB-INF/lib/remoting-3.35.jar /engn001/csvn/.jenkins/plugins/maven-plugin/WEB-INF/lib/maven31-interceptor-1.5.jar /engn001/csvn/.jenkins/plugins/maven-plugin/WEB-INF/lib/maven3-interceptor-commons-1.5.jar 44826
Exception in thread "main" java.lang.UnsupportedClassVersionError: hudson/remoting/Launcher : Unsupported major.minor version 52.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClassFromSelf(ClassRealm.java:386)
at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:42)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:244)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:230)
at jenkins.maven3.agent.Maven31Main.main(Maven31Main.java:138)
at jenkins.maven3.agent.Maven31Main.main(Maven31Main.java:67)

 

해결책 : Jenkins 에서 New Item > Freestyle project 를 선택하여  Build 항목에 "Invoke top-level Maven targets"

를 선택하여 처리한다.

 

Spring Framework 5.2 는 context 에 url 이 http가 아니라 https (ssl)로 시작된다.

spring-security-config.jar/META-INF/spring-schemas에 정의됨(이전 버전들은 spring-context.jar 에 정의됨)

xmlns:security="http://www.springframework.org/schema/security" 을 사용하기 위해서는 아래와 같이 정의해야 함.

http://www.springframework.org/schema/security  https://www.springframework.org/schema/security/spring-security.xsdhttps://www.springframework.org/schema/security/spring-security.xsd]

1. properties file : 

<bean org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

 <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="locations">
    <list>
        <value>classpath:config/system.properties</value>
    </list>
  </property>
  <property name="ignoreResourceNotFound" value="true" />
  <property name="searchSystemEnvironment" value="true" />
  <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
  </bean>
public class PropertiesUtil extends PropertyPlaceholderConfigurer {
	/**LOGGER SET **/
	private static final Logger LOGGER = LogManager.getLogger(PropertiesUtil.class);
	
	@Autowired 
	private Environment environment;
	 
	private static Map<String, String> propertiesMap;
    // Default as in PropertyPlaceholderConfigurer
    private int springSystemPropertiesMode = SYSTEM_PROPERTIES_MODE_FALLBACK;

    @Override
    public void setSystemPropertiesMode(int systemPropertiesMode) {
        super.setSystemPropertiesMode(systemPropertiesMode);
        springSystemPropertiesMode = systemPropertiesMode;
    }


    @Override
    protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props) throws BeansException {
        super.processProperties(beanFactory, props);

        propertiesMap = new HashMap<String, String>();
        for (Object key : props.keySet()) {
            String keyStr = String.valueOf(key);
            String valueStr = resolvePlaceholder(keyStr, props, springSystemPropertiesMode);
            propertiesMap.put(keyStr, valueStr);
            if(environment !=null)
            	LOGGER.debug("Load Properties: env:{}" ,environment.getProperty(keyStr));
           	LOGGER.debug("Load Properties: {}:{}, env:{}" ,keyStr, valueStr,"te");
      
        }
    }

    /**
     * This method return value with the name from properties map
     * @param name propertiy name
     * @return
     */
    public static String getString(String name)  {
        return propertiesMap.get(name).toString();
    }
    
    public static int getInt(String name) {
    	if (propertiesMap.get(name) != null || propertiesMap.get(name) != "") {
            return Integer.parseInt(String.valueOf(propertiesMap.get(name)));    		
    	}
    	else {
    		return 0;
    	}
    }

    public static long getLong(String name) {
    	if (propertiesMap.get(name) != null || propertiesMap.get(name) != "") {
            return Long.parseLong(String.valueOf(propertiesMap.get(name)));    		
    	}
    	else {
    		return 0;
    	}
    }
}

2. Envrionment  eclipse tomcat server "Open launch configuration" > environment 탭

3. Java Compile option "-D...."

 

 

ref. https://stackoverflow.com/questions/45822326/precedence-order-among-properties-file-yaml-file-and-command-line-arguments-in

 

Spring Boot uses a very particular PropertySource order that is designed to allow sensible overriding of values. Properties are considered in the following order:

  1. Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
  2. @TestPropertySource annotations on your tests.
  3. @SpringBootTest#properties annotation attribute on your tests.
  4. Command line arguments.
  5. Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property)
  6. ServletConfig init parameters.
  7. ServletContext init parameters.
  8. JNDI attributes from java:comp/env.
  9. Java System properties (System.getProperties()).
  10. OS environment variables.
  11. A RandomValuePropertySource that only has properties in random.*.
  12. Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants)
  13. Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants)
  14. Application properties outside of your packaged jar (application.properties and YAML variants).
  15. Application properties packaged inside your jar (application.properties and YAML variants).
  16. @PropertySource annotations on your @Configuration classes.
  17. Default properties (specified using SpringApplication.setDefaultProperties).

1. Nginx 우선순위

location / {


root /usr/local/openresty/nginx/html;  

#경로의 index.htm 이나, index.html 호출.  아래의 확장자 location으로 search 가 진행됨.

}


location ~ \.(htm|html|ico|jhtm|PDF|png|zip|ZIP|unity3d|jpeg|ai|bin|dat|dwg|dxf) {

    root /images

}


확장자  location에서 root /images 로 변경되어,  html 파일을 /images 경로에서 찾게됨.

1. 목적: 크래커를 통해 평문인 패스워드가 탈취되었을 때 그 패스워드를 사용하여 로그인이 가능하다.


2. 이슈: 프로젝트 상황이 TLS(HTTPS)를 사용할 수 없는 상황에서 크래커가 네트워크 중간에서 패스워드를 탈취하여 시스템에 접속할 수 있는 보안 문제가 발생함.


3. 이미 구축된 시스템은 

       1) 사용자 등록 시 패스워드를 SHA256으로 암호화 되어 서버에 저장함.

       2) 사용자가 로그인 하는 경우 웹화면으로 부터 ID/PW 를 입력 받아 DB에서 입력받은 ID/PW를 이용해 조회한 후, 입력받은 PW를 동일한 방식         (SHA256)으로 암호화 하여 조회된 PW와 비교하는 방식으로 인증 처리함.


4. 해결: 웹 화면에서 스크립트를 이용하여 서버에 저장된 같은 방식으로 SHA256 암호화 하여 전송함.

- SHA256으로 암호화하는 경우도 salt가 동일하여 Hash 값 역시 일정한 값으로 네트워크 중간에 패스워드를 탈취하는 해킹을 피해갈 수 없음.

- 매번 값을 변경하기 위해 BCrypt를 사용하여 암호화 하였으나, 이 역시 SALT 가 포함되어 있어 이미 사용된 패스워드 해쉬값을 계속 사용할 수 있음.

- 최종 해결책은 처음 시스템 접속시 생성된 Session ID 값을 같이 암호화 하여 처리함.


* 자세한 내용은 퇴근시간이 다되서 여기에 적지 않음~~~ 

1. 목적 : Excel 파일로 다운로드시 HTML Tag 없이, 순수 Text 만 저장함


2. 이슈 : Intercept 등을 이용해 데이터 컨버전을 하게되면, 다량의 데이터를 내려받는 업무에서 속도가 30% 정도 느려지는 현상 발생. 


3. 상황 

1) 프로젝트에서 웹 에디터를 이용하여 컨텐츠를 저장함. 이 에디터로 저장된 컨텐츠들은 HTML Tag 가 포함되어 있음


2) DB에 저장될 때 HTML Tag를 포함한 데이터들은 XSS 보안을 위해 Encoding data 로 변환하여 저장됨

    예] 

Hello World<br />

<em><strong>Hello World</strong></em>

==>

Hello World&lt;br /&gt;

&lt;em&gt;&lt;strong&gt;Hello World&lt;/strong&gt;&lt;/em&gt;


3) DB에 저장될 때 HTML Tag를 포함한 데이터들은 XSS 보안을 위해 Encoding data 로 변환하여 저장됨 


4. 해결

     1) 오라클의 내장 함수 REGEXP_REPLACE, DBMS_XMLGEN.CONVERT 사용

          DBMS_XMLGEN.CONVERT 를 사용하여 Encoding 값을 HTML Tag로 변환 후 REGEXP_REPLACE 을 이용하여 HTML Tag 는 빈 값으로 변경한다.

       예]

          REGEXP_REPLACE(DBMS_XMLGEN.CONVERT(HTML_ENCODED_DATA, 1), '<[^>]*>|\&([^;])*;', '') AS ONLY_TEXT_DATA

      

5. Encoding 값을 곧바로 REGEXP_REPLACE 를 사용하여 변경할 수도 있을거 같으나, 100% 만족하는 규칙을 찾을 수 없어, 위와 같이 처리함.

+ Recent posts