728x90

RSA 암호화/복화화 시 실시간으로 KEY 조합이어야 할 경우에는 어떻게 접근해야 할까?

실시간이라는 의미는 매번 접속할 때마다 RSA 암호화/복화화 KEY가 달라진다는 것이다.

HDD 에 저장된 Public KEY, Private KEY 가 아니라 메모리 상에서 접속시마다 생성하는 KEY 쌍이다.

최근의 보안검증에서는 이런 걸 요구하고 있다.

해킹 시도를 원천 차단하고자 하는 것이 목적이기 때문일 것이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
if(!isset($_SESSION)) {
    session_start();
}
require_once 'path.php';// root 폴더를 기준으로 상대적인 경로 자동 구하기
require_once $g['path_root'].'deviceChk.php';
require_once $g['path_config'].'config.php';
require_once $g['path_class'].'dbconnect.php';
require_once $g['path_class'].'loginClass.php';
$c = new LoginClass();
 
$salt = sha1(rand());
$salt = substr($salt020);
 
$key = $c->rsa_generate_keys($salt);
$pubkey = $c->rsa_publickey($key['pub_key']);
$prikey = $c->rsa_privatekey($key['pri_key']);
$_SESSION['prikey'= $prikey;
$_SESSION['salt'= $salt;
 
// JSON 응답으로 공개키 전달
header('Content-Type: application/json');
echo json_encode(["pub_key" => $pubkey]);
 
/*
echo json_encode([
    "pub_key" => $pubkey,
    "session_id" => session_id(),
    "prikey" => isset($_SESSION['prikey']) ? $_SESSION['prikey'] : "NOT_SET",
    "salt" => isset($_SESSION['salt']) ? $_SESSION['salt'] : "NOT_SET",
]);
 
// */
?>

 

위 코드와 같이 PHP SESSION 으로 Private KEY를 전달한다.

KEY 쌍을 생성할 때 salt 를 적용하면 변화가 더욱 심해진다.

 

이런 점을 감안해서 JMeter 에서 암호화 로그인을 성공하기 위한 과정이다.

처음부터 부하를 많이 주는 테스트를 하면 안되고 로그인까지 정상적으로 되는지 확인해야 하기 때문에 1로 설정한다.

 

 

 

JSON Path expression 을 왜 이렇게 설정했는지는 위 PHP 소스코드를 보면 알 수 있다.

만약 data 배열 하단에 pub_key 로 생성하면 $.data.pub_key 로 변경해줘야 한다.

 

PHP SESSION 을 변수에 담아서 저장하기 위한 과정이다.

매번 HTTP Request 추가하여 실행될 때 마다 다른 PHPSESSID 가 생성될 수 있으니 필요한 곳에 값을 전달하면 된다.

 

 

추출한 PHP SESSION 값을 변수에 저장하는 과정이다.

 

 

공개키 가져오는 과정이다. JSR223 PreProcess 를 사용하여 변수를 가져와 암호화된 비밀번호를 생성할 수 있다.

 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 
import java.security.KeyFactory
import java.security.spec.X509EncodedKeySpec
import java.security.PublicKey
import javax.crypto.Cipher
import org.apache.commons.codec.binary.Base64
 
// JSON Extractor에서 추출한 공개 키 가져오기
String publicKeyString = vars.get("pubkey");
 
// Debugging: JMeter log에서 확인 가능
log.info("Extracted Public Key: " + publicKeyString);
 
if (publicKeyString == null || publicKeyString.equals("NOT_FOUND"|| publicKeyString.isEmpty()) {
    throw new RuntimeException("Public Key not found in response! Check JSON Extractor.");
}
 
// 암호화할 비밀번호 가져오기
String password = vars.get("password");
 
// 공개 키 복원
byte[] keyBytes = Base64.decodeBase64(publicKeyString);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(spec);
 
// RSA 암호화 수행
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedBytes = cipher.doFinal(password.getBytes("UTF-8"));
 
// Base64로 인코딩
String encryptedPassword = Base64.encodeBase64String(encryptedBytes);
 
// JMeter 변수 저장
vars.put("encryptedPassword", encryptedPassword);
log.info("Encrypted Password: " + encryptedPassword);
 

 

 

로그인할 때 userID와 password 를 앞에서 생성한 encryptedPassword 를 입력변수로 전달한다.

Front-End 단의 코드는 필요없고, Back-End 단의 PHP 가 POST 변수로 받는 부분을 고려하면 된다.

 

 

Header 메시지는 웹브라우저의 개발자모드에서 확인한 사항을 적어둔다.

Cookie 에 앞에서 추출한 PHPSESSID를 변수로 적어준다.

 

 

 

토큰 추출 관련 PHP 소스코드

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<?php
if(!isset($_SESSION)) {
    session_start();
}
error_reporting(0);
 
header('Content-Type: application/json');
/*
echo json_encode([
    "session_id" => session_id(),
    "prikey" => isset($_SESSION['prikey']) ? $_SESSION['prikey'] : "NOT_SET",
    "salt" => isset($_SESSION['salt']) ? $_SESSION['salt'] : "NOT_SET",
]);
exit;
// */
// jwt 라이브러리 사용
use \Firebase\JWT\JWT;
 
// 파일을 직접 실행하는 비정상적 동작을 방지 하기 위한 목적
if(isset($_POST&& $_SERVER['REQUEST_METHOD'== "POST"){
    @extract($_POST);
    if(isset($userID&& !empty($userID&& isset($password&& !empty($password)) {
        require_once 'path.php';
        require_once $g['path_config'].'config.php';
        require_once $g['path_class'].'dbconnect.php';
        require_once $g['path_class'].'loginClass.php';
        require_once $g['path_root'].'vendor/autoload.php';
        $c = new LoginClass();
 
        $private_key = $_SESSION['prikey'];
        $salt = $_SESSION['salt'];
 
        $password = $c->rsa_decrypt_key($password$private_key,$salt); // RSA 패스워드 복호화 기능 구현
                
        $rs = $c->LoginSuccessChk($userID,$password); // 개발 서버
        $rs = (int)$rs;
        switch($rs){
            case 11:
                // 로그인 허용
                $user = $c->getUser($userID$password);
                if ($user != false) {
                    $issuedAt = time();
                    $expirationTime = $issuedAt + 3600// 1시간 유효
                    if($user['admin']==1 || $user['admin']==2) {
                        $payload = array(
                            'iat' => $issuedAt,
                            "exp" => $expirationTime,
                            "userID" => $user['userID'],
                            "userNM" => $user['userNM'],
                            "access" => $user['access'],
                            "usrIDX" => $user['idx'],
                            "orgId" => $user['orgId'],
                            "authID" => $user['admin'],
                        );
                        $rs = 21;
                    } else {
                        $payload = array(
                            'iat' => $issuedAt,
                            "exp" => $expirationTime,
                            "userID" => $user['userID'],
                            "userNM" => $user['userNM'],
                            "access" => $user['access'],
                            "usrIDX" => $user['idx'],
                            "orgId" => $user['orgId'],
                        );
                    }
 
                    // JWT 생성
                    $token = JWT::encode($payload, SECRET_KEY, ALGORITHM);
 
                    // 세션 및 쿠키 저장
                    //$_SESSION['token'] = $token;
                    setcookie('token'$tokentime() + 3600'/'); // 1시간 동안 쿠키 저장
                    
                    header('Content-Type: application/json');
                    echo json_encode(array('token' => $token));
 
                } else {
                    echo json_encode(array('result' => '-3')); // 체크 필요
                }
                break;
 
            default:
                echo json_encode(array('result' => $rs));
                break;
        }
    } else {// 입력받은 데이터에 문제가 있을 경우
        echo json_encode(array('result' => '-2'));
    }
else { // 비정상적인 접속인 경우
    echo json_encode(array('result' => '-3')); // loginChk.php 파일을 직접 실행할 경우에는 화면에 0을 찍어준다.
    exit;
}
?>

 

 

 

로그인 이후의 파일에 접근하는 과정 설명 그림이다.

 

 

 

 

 

이 정도면 충분한 설명은 되었다고 본다.

소스코드를 분석하면서 JMeter 스크립트 과정을 작성해야 하는 거 같다.

 

본문내에 광고가 떠서 가독성을 떨어뜨리는 거 같아서 광고를 삭제시켰다.

블로그 접속빈도가 떨어져서 광고를 클릭할 가능성도 매우 낮다고 보기 때문이고, 정보 전달의 목적에 충실하자는 의도도 있다.

728x90
블로그 이미지

Link2Me

,
728x90

JMeter 에서 RSA 암호화 로그인 방법을 찾으려고 개고생을 했다.

구글링으로 원하는 답을 구하지 못했고 chatGPT도 엉터리 답변 때문에 수많은 시간을 낭비했다.

Javascript 에서 jsencrypt.min.js 라이브러리를 활용하여 RSA 암호화를 하기 때문에 이 코드 찾는 방법에 수많은 시간을 허비 했던 것이 가장 큰 오류중의 하나였다.

이기종 언어간에 RSA 암호화/복호화 가능하기 때문에 Java에서 제공하는 RSA 암호화 로직을 활용하면 된다.

 

자세한 설명은 생략하고 이미지 순서에 따라 처리하면 된다.

처음에는 로그인이 성공하는지 확인하기 위한 목적이니 2번과 같이 1회로 한정한다.

 

공개키 추출하는 방법

- 공개키를 JSON 으로 반환하도록 처리해야 한다.

 

 

JSON 으로 제공된 pub_key 를 추출하여 pubkey 변수에 저장하기 위한 목적이다.

가장 크게 삽질한 것은 JSR223 PreProcessor 부분이다. 바로 변수로 저장할 수 있는 줄 알고 했는데 ㅠㅠㅠ

 

 

변수를 저장하기 위해서 HTTP Request 를 추가하고 pubkey 변수를 입력받도록 파라미터를 아래와 같이 지정한다.

 

 

 

 

21번 항목의 코드 내용이다.

아래 코드에서 vars.get("pubkey") 의 pubkey 가 입력변수이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import java.security.KeyFactory
import java.security.spec.X509EncodedKeySpec
import java.security.PublicKey
import javax.crypto.Cipher
import org.apache.commons.codec.binary.Base64
 
// JSON Extractor에서 추출한 공개 키 가져오기
String publicKeyString = vars.get("pubkey");
 
// Debugging: JMeter log에서 확인 가능
log.info("Extracted Public Key: " + publicKeyString);
 
if (publicKeyString == null || publicKeyString.equals("NOT_FOUND"|| publicKeyString.isEmpty()) {
    throw new RuntimeException("Public Key not found in response! Check JSON Extractor.");
}
 
// 암호화할 비밀번호 가져오기
String password = vars.get("password");
 
// 공개 키 복원
byte[] keyBytes = Base64.decodeBase64(publicKeyString);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(spec);
 
// RSA 암호화 수행
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedBytes = cipher.doFinal(password.getBytes("UTF-8"));
 
// Base64로 인코딩
String encryptedPassword = Base64.encodeBase64String(encryptedBytes);
 
// JMeter 변수 저장
vars.put("encryptedPassword", encryptedPassword);
log.info("Encrypted Password: " + encryptedPassword);
 

Java 에서의 RSA 암호화가 다른 언어에서 복호화가 가능하다.

Javascript 에서는 jsencrypt.min.js 라이브러리를 활용하여 RSA 암호화가 가능하다.

하지만 JMeter 에서는 javascript 암호화를 지원하지 않기 때문에 Java RSA 암호화를 활용하는 것이다.

 

vars.put(" encryptedPassword ") 가 아래 그림에서 패스워드 입력값이다.

 

나머지 사항은 이전 게시글 내용과 이미지를 참조하면 된다.

RSA 암호화 시 KEY 쌍이 실시간으로 변경되는 경우에 대한 처리는 아직 테스트하지 못했다. → 테스트 성공했다. 이 경우는 다른 게시글에서 올리겠다.

RSA 암호화/복호화 시 사용할 KEY 쌍이 일정시간동안 변경되지 않는 방식인 경우를 테스트 후 성공했다.

 

 

 

 

 

chatGPT 에게 제대로 된 답변을 알려줬다.

728x90
블로그 이미지

Link2Me

,
728x90

먼저 token 인증을 할 환경을 구축해야 한다.

JWT 토큰 인증 환경 구성 이해하는데 시간이 좀 걸렸다. 이 부분은 필요하면 나중에 설명하겠다.

 

설명은 그림 위주로 설명을 할 것이다.

로그인 처리 없이 JMeter 부하테스트하는 것은 어렵지 않게 찾을 수 있다.

 

처음에는 Thread 숫자를 1로 놓고 확인해야 한다. Loop Count 도 1로 설정한다.

2번 Thread Group 이라는 명칭을 주의깊게 보자. 앞으로 반복되는 이미지에서 2번 위치에 표기되는 항목 명칭을 보면 이해가 빠르게 될 것이다.

 

Threads Group
- continue : 에러가 발생해도 테스트를 계속 진행
- Start Next Thread Loop : 현재 쓰레드의 루프를 종료하고 다음 루프를 시작
- Stop Thread : 에러가 발생한 쓰레드만 종료
- Stop Test Now : 현재 실행중인 모든 샘플러를 강제로 중지하고 테스트를 즉시 종료

 

목표

- HTTP 요청을 통해 로그인 API 호출
- JSON 응답에서 토큰 추출
- 추출된 토큰을 이후 요청에 활용할 수 있도록 저장

 

HTTP Request 추가하고, Name을 로그인으로 변경했다.

 

 

Path 에 도메인 주소를 적어줬다. Virtual Host 로 여러개 설정한 환경에서 테스트해보니 첫번째 URL을 인식하더라.

그래서 테스트하고 싶은 도메인을 상단으로 올리고 클라우드 서버를 재기동해줬다.

7번 항목은 loginView.php 에서는 RSA 암호화를 하고 jwtLoginChk.php 파일에서는 RSA 복호화를 한 다음에 로그인에 성공하면 jwt 토큰인증을 생성하도록 처리한다.

하지만 JMeter 에서 RSA 암호화 생성하고 로그인처리하는 것은 쉽지 않는 거 같아서 jwtLoginChk2.php 파일을 생성하고 RSA 복호화처리하는 부분을 주석처리하고 8번 userID, password 를 입력받아 토큰 생성을 하도록 임시 변통했다.

JMeter에서는 JavaScript를 직접 실행할 수 없으므로, 사전에 암호화된 값으로 요청해야 한다.

하지만 Java 코드로 RSA 암호화하는 방법이 있더라. 다른 언어를 같이 다뤄보지 않았으면 해결방법 찾기가 쉽지 않을 수 있다.

 

로그인 하위에 HTTP Header Manager 를 추가한다.

12번 항목에 나오는 사항은 실행을 했을 때 반환하는 결과를 보고 찾아서 입력하면 된다.

 

 

로그인 결과로 반환하는 JSON 메시지에서 토큰을 자동 추출하기 위한 과정이다.

 

JSON 응답에서 토큰 추출
   JSON Extractor 추가 (HTTP Request 하위에 추가)
    Names of created variables: authToken
    JSON Path expressions: $.token
    Match No: 1
    Default Value: NOT_FOUND

 

 

로그인 후 쿠키/세션 처리
  로그인 성공 시, 응답 헤더에 Set-Cookie가 포함될 수 있다.
  HTTP Cookie Manager를 추가하여 이후 요청에서도 쿠키를 유지해야 한다.

 

 

토큰이 잘 생성되고 있는지 확인하기 위해 View Results Tree 를 추가해준다.

 

 

 

 

JSON 응답 확인 및 토큰 추출
  View Results Tree에서 응답 확인
  JSON 응답이 오면 JSON Extractor 추가하여 $.token 값 추출

 

 

Debug Sampler 에서 값이 잘 추출되고 있는지 확인할 수 있다.

 

 

로그인 이후의 URL 에 접속 테스트 설정

 

 

 

 

 

 

Label: 요청했던 Request Sampler의 이름
Samples: 서버에 요청한 횟수
Average: 평균응답시간(ms)
Min: 최소응답시간(ms)
Max: 최대응답시간(ms
Std.Dev.: 표준편차 요청에 대한 응답시간이 일정하고 안정적인가를 확인한다. 값이 적을수록 안정적이다.
Error: Error율(%)
Throughput: 처리량( 초당 처리건수)
KB/sec: 처리량(초당 처리 KB)

728x90

'Web 프로그램 > JMeter' 카테고리의 다른 글

JMeter real-time RSA 암호화 로그인 방법  (0) 2025.02.22
JMeter RSA 암호화 로그인 방법  (2) 2025.02.21
블로그 이미지

Link2Me

,
728x90

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import requests
from bs4 import BeautifulSoup
import pandas as pd
 
def crawl_orgchart(url):
 
    # 요청 및 응답 확인
    headers = {
        "User-Agent""Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
    }
    response = requests.get(url, headers=headers)
    soup = BeautifulSoup(response.text, "html.parser")
 
    # 데이터 저장 리스트
    data = []
 
    departments = soup.select(".contents_db h5.tit_05")
    tables = soup.select(".contents_db table")
 
    # 테이블 데이터 추출
    for dept, table in zip(departments, tables):
        department_name = dept.text.strip()
 
        table_rows = table.select("tbody tr")
        for row in table_rows:
            columns = row.find_all("td")
            if len(columns) >= 3:
                position = columns[0].get_text(strip=True)  # 직위
                duty = columns[1].get_text(strip=True)  # 담당업무
                phone = columns[2].get_text(strip=True)  # 행정전화번호
                data.append([department_name, position, phone, duty])
 
    columns = ["부서명""직위""전화번호","담당업무"]
    df = pd.DataFrame(data, columns=columns)
    return df
 
if __name__ == "__main__":
    urls = [
        "https://www.jongno.go.kr/dong/member/findEmpList.do?menuId=218292&menuNo=218292&dong=01",
        "https://www.jongno.go.kr/dong/member/findEmpList.do?menuId=228292&menuNo=228292&dong=02",
        "https://www.jongno.go.kr/dong/member/findEmpList.do?menuId=238292&menuNo=238292&dong=03",
        "https://www.jongno.go.kr/dong/member/findEmpList.do?menuId=248292&menuNo=248292&dong=04",
        "https://www.jongno.go.kr/dong/member/findEmpList.do?menuId=258292&menuNo=258292&dong=05",
        "https://www.jongno.go.kr/dong/member/findEmpList.do?menuId=268292&menuNo=268292&dong=06",
        "https://www.jongno.go.kr/dong/member/findEmpList.do?menuId=278292&menuNo=278292&dong=07",
        "https://www.jongno.go.kr/dong/member/findEmpList.do?menuId=288292&menuNo=288292&dong=08",
        "https://www.jongno.go.kr/dong/member/findEmpList.do?menuId=298292&menuNo=298292&dong=09",
        "https://www.jongno.go.kr/dong/member/findEmpList.do?menuId=308292&menuNo=308292&dong=10",
        "https://www.jongno.go.kr/dong/member/findEmpList.do?menuId=318292&menuNo=318292&dong=11",
        "https://www.jongno.go.kr/dong/member/findEmpList.do?menuId=328292&menuNo=328292&dong=12",
        "https://www.jongno.go.kr/dong/member/findEmpList.do?menuId=348292&menuNo=348292&dong=14",
        "https://www.jongno.go.kr/dong/member/findEmpList.do?menuId=358292&menuNo=358292&dong=15",
        "https://www.jongno.go.kr/dong/member/findEmpList.do?menuId=368292&menuNo=368292&dong=16",
        "https://www.jongno.go.kr/dong/member/findEmpList.do?menuId=378292&menuNo=378292&dong=17",
        "https://www.jongno.go.kr/dong/member/findEmpList.do?menuId=388292&menuNo=388292&dong=18"
    ]
    
    # 모든 URL에서 데이터 크롤링
    dataframes = [crawl_orgchart(url) for url in urls]
    
    # 데이터프레임 병합
    df_combined = pd.concat(dataframes, ignore_index=True)
    
    # 두 데이터프레임을 합치기
    if not df_combined.empty:
        print(df_combined)
        df_combined.to_csv("종로구청_동주민센터.csv", index=False, encoding="utf-8-sig")
 
 

 

 

728x90
블로그 이미지

Link2Me

,
728x90

PHP 에서 DB 와 연결해서 TreeView 처리하는 코드 예제이다.

Treeview 의 깊이를 좁게 처리하기 위해서 style 을 수정했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<?php
error_reporting(0); // 경고 출력 없애기
//*
ini_set("display_startup_errors"1);
ini_set("display_errors"1);
error_reporting(E_ALL);
// */
 
require_once 'path.php';// root 폴더를 기준으로 상대적인 경로 자동 구하기
require_once $g['path_root'].'sessionChk.php'// 세션 체크
require_once $g['path_config'].'config.php';
require_once $g['path_class'].'dbconnect.php';
require_once $g['path_class'].'adminClass.php';
$a = new adminClass();
$dbInstance = new DBDataClass();
$db = $dbInstance->db;
 
date_default_timezone_set('Asia/Seoul');
 
// Function to fetch categories
function fetchCategories($parent_id = null$db) {
    $stmt = $db->prepare("SELECT * FROM categories WHERE parent_id " . ($parent_id ? "= :parent_id" : "IS NULL"));
    if ($parent_id) {
        $stmt->bindParam(':parent_id'$parent_id, PDO::PARAM_INT);
    }
    $stmt->execute();
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
 
// Recursive function to build tree
function buildTree($parent_id = null$db) {
    $categories = fetchCategories($parent_id$db);
    if (count($categories> 0) {
        echo '<ul class="nested">';
        foreach ($categories as $category) {
            echo '<li data-id="' . $category['id'] . '">' . $category['name'];
            buildTree($category['id'], $db);
            echo '</li>';
        }
        echo '</ul>';
    }
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PHP Treeview with MySQL and jQuery</title>
    <style>
        ul {
            list-style-type: none;
            padding-left: 10px;
        }
        li {
            cursor: pointer;
            padding: 5px;
        }
        .nested {
            display: none; /* 기본적으로 닫힌 상태 */
        }
    </style>
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
</head>
<body>
    <h1>Category Treeview</h1>
    <div id="treeview">
        <?php buildTree(null$db); ?>
    </div>
 
    <script>
        $(document).ready(function () {
            // Initially hide all nested lists
            $(".nested").show();
 
            // Toggle visibility on click
            $("#treeview li").click(function (e) {
                $(this).children("ul").slideToggle();
                e.stopPropagation(); // Prevent event bubbling
            });
        });
    </script>
</body>
</html>

 

 

MySQL 테이블 구조

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
CREATE TABLE categories (
  id int(11NOT NULL,
  name varchar(255NOT NULL,
  parent_id int(11DEFAULT NULL
ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;
 
INSERT INTO categories (id, name, parent_id) VALUES
(1'Electronics'NULL),
(2'Laptops'1),
(3'Smartphones'1),
(4'Dell'2),
(5'HP'2),
(6'Samsung'3),
(7'Apple'3);
 
ALTER TABLE categories
  ADD PRIMARY KEY (id),
  ADD KEY parent_id (parent_id);
 
ALTER TABLE categories
  MODIFY id int(11NOT NULL AUTO_INCREMENTAUTO_INCREMENT=8;
 
ALTER TABLE categories
  ADD CONSTRAINT categories_ibfk_1 FOREIGN KEY (parent_id) REFERENCES categories (id) ON DELETE CASCADE;
COMMIT;

 

categories.sql
0.00MB

 

728x90
블로그 이미지

Link2Me

,
728x90

리눅스에서 제공하는 파일 인코딩 변환을 사용해봤는데 모두 ANSI 로 된 인코딩 모드를 UTF-8 로 변환하는 걸 제대로 처리하지 못한다.

 

Rocky Linux 9.5 및 CentOS 7.9 에서 모두 해봤는데 한글이 깨져서 변환처리를 한다.

 

파일을 나누어서 EditPlus 가 읽어들일 수 있는 용량 크기로 만들어서 인코딩 모드를 변환하는 것이 가장 확실한 방법이다.

 

 

 

728x90
블로그 이미지

Link2Me

,
728x90

주식에서 가장 위험한 것은 99번 성공하고 1번 실패하면 망한다는 것이다.

주식은 진입장벽이 낮아서 아무나 할 수 있지만, 쉽게 보고 덤비면 손실을 너무 많이 보는 도박판이 되기도 한다.

테마성으로 움직이는 주식은 매출실적없는 경우 언제든 대폭락할 우려가 있다는 걸 알아야 하는데 그걸 간과하기 쉽다.

 

 

2024년 11월 10일부터 미국주식에 입문했다.

미국주식 공부하면서 10배 오를 종목 발굴하는 방법을 배우고 싶다는 열망이 강하다.

초보수준으로 몇가지 종목을 분석하면서

1. PLUG 파워

수소종목으로 최고가 71달러까지 올랐다가 현재 주가는 1.6달러 최저가에서 약간 반등하여 2달러 수준이다. 수소산업 시장 영상을 수도 없이 찾아보니 아직은 수소산업시대가 되려면 멀었다는 것이다.

그럼에도 불구하고 주가가 최대 71달러까지 찍었을 때에는 테마성으로 핫하게 움직였을 가능성이 매우 높다.

2달러대는 바닥으로 미국이 수소산업을 포기하면 상폐될 가능성이 높겠지만, 수소시대를 대비해서 보조금 등을 지급한다면 지금 주식은 바닥권으로 볼 수 있지 않을까? 운용할 현금이 확보되지 않으면 언제든지 무너질 가능성이 있기 때문에 장기투자 종목으로 분류하기는 어렵기에 소액투자 정도가 적정한 거 같다.

천연수소 시추를 프랑스, 러시아, 미국, 호주, 아프리카 등에서 하고 있는데 천연수소 시추에 성공하면 수소산업시대가 예상보다 빨리 오게되고 산업의 패러다임이 바뀌게 될 강력한 에너지원이다.

 

2. 텔러닥 헬스

원격의료 종목으로 뜨거운 관심을 받으면서 2021년도 최고가 308달러까지 상승했던 주가가 현재 10달러 미만이다.

우리나라의 경우에도 의사들이 원격진료하는 것에 매우 부정적인데 과연 이것이 쉽게 될까하는 분석없이 매수했었다면 엄청난 계좌 손실이 발생하고 있었을 것이다.

AI 와 접목하면서 원격의료 시장이 활성화될 수 있을까? 아직 이 분야 자료를 찾아보지 않아서 모르겠다.

AI + 양자컴퓨팅 시대가 되면 가장 혜택받은 분야는 바이오 분야일 거 같다.

 

3. 양자컴퓨팅

양자컴퓨팅 종목은 매출 실적도 없으면서 테마성으로 상승하는 대표적인 종목이라고 본다.

아직 상용화까지는 시간이 좀 걸릴 것으로 예상되어 언제 대폭락이 오게될지 몰라서 매수 대상에서 제외하고 있다.

 

4. 로켓랩

올랜도킴 영상에서 찾아보다 알게 된 종목이다. 추천시점에는 13달러였는데 내가 미국주식하고 접한 시점의 주가는 24달러였다. 여러 영상을 찾아보니 실적도 좋고 성장 가능성이 좋은 회사인 거 같다.

그럼에도 불구하고 17달러까지 떨어지면 매수할거야 하는 생각이 강해서 소액으로 매수를 했다가 약간의 수익을 보고 매도를 하는 정도다. 올랜도킴 영상 분석으로 배운 것은 흑자전환 예상시점까지 현금보유 수준과 흑자전환 시점을 선반영하여 주가가 움직이는 점을 고려하면 2025년 하반기, 2026년에는 지금보다 주가가 더 오를 거 같다는 점이다.

조정받으면 매수할 주식 중 하나라고 본다. 지지선이 22달러 선인거 같다.

 

5. UiPATH

UiPATH는 미국, 루마니아, 영국, 네덜란드 및 국제적으로 주로 활동하는 로봇 프로세스 자동화(RPA) 솔루션의 선도적 공급업체이다. 54%의 순이익 성장률로 강력한 성장을 보이며, 업계의 8%를 크게 앞지른다. 매출 총이익율 83%는 업계 평균 51%보다 상당히 높아 수익성이 강하지만, EBITA 마진이 -10%로 어려움을 겪고 있으며, 긍정적인 업계 중간값 10%와는 대조적이다. 부채없는 대차대조표와 강력한 재무 건전성으로 인정받고 있다.

현재 주가 13달러 미만이면 저점이라고 보지만 미국 증시가 하락하면 같이 하락할 거 같아 저점이 어디인지 알수는없을 거 같다.

인력감축이 2025.4월까지 진행완료되면 수익은 더 좋아질 것으로 보고, AI 접목으로 매출 상승이 기대된다.

애널리스트 중에서 매수 추천자도 있지만, 생성형 AI의 발전과 AI Agent의 시대가 되면 될수록 우려하는 애널리스트도 있는 거 같다.

 

6. UAM 종목 Joby, Archer

항공택시 UAM 종목으로 Joby 와 Archer가 똘똘한 종목인거 같다. 엄청난 투자비가 들어가는 종목이라 대규모 투자 지원을 받아서 진행하는 거 같다. 하늘의 테슬라라 불리는 조비는 2025년말 상용화 목표로 진행중이다.

도심항공을 넘어서 도시간에 이동도 할 수 있는 수소연료전지 기반 HeVTOL 도 시험비행에 성공했다.

적정주가는 7달러선으로 본다. 주가는 8달러 미만이 되면 다시 반등하는 경향이 있다. 테스트 통과 등 언론 기사가 나오면 반등해서 15달러, 20달러까지 상승했다가 다시 10달러 미만으로 떨어져도 이상하지 않다고 본다. 상용화를 한다고 해도 흑자전환 시기는 언제가 될지 장담하지 못하고 있다. 추락사고가 발생하면 사망사고로 이어지기 때문에 주가 하락의 요인은 언제든지 발생할 수 있다.

주가는 흑자전환시점 이후 10배까지 오르는 거 같다. 2030년까지 장기 보유를 해야겠다면 저점매수해서 마음고생하지 말아야 한다.

 

안전투자 한다면 아래 3종목이 좋을 거 같다.

1. 테슬라

2. 팔란티어 : 60달러대까지 하락하면 매수. 전문가 예상 주가 전망 170달러

3. 로켓랩 : 21달러 1차 지지선, 17달러 2차 지지선

 

 

주식으로 돈을 번 사람은 주식/경제 서적 50~60권 정도 보고나서 모의투자하고 돈을 벌었다는 분의 얘기를 들었다.

직장생활하면서 이렇게 책을 보기는 정말 쉽지 않다.

유투브에 넘쳐나는 영상을 보기에서 시간은 턱없이 부족해 보인다.

재무제표 볼 줄 아직 모른다. 단기 투자자에게는 재무제표는 크게 중요하지 않을 수도 있다.

재무제표는 과거의 데이터일 뿐, 미래의 성장 전망은 못한다. 그럼에도 불구하고 반드시 공부해야하는 영역이다.

미국주식 카페 댓글을 보면 미국 빅테크 종목, ETF 종목에 안전투자하고 위험종목에는 5% 미만으로 투자하는 거 같다.

728x90
블로그 이미지

Link2Me

,
728x90

미국주식 초보로서 마음 아프게 손실이 크다.

많은 영상을 찾아보면서 영상에 나온 사이트 정보를 참조하면서 스스로 분석해보겠다는 의지로 덤비다가 완전 손실을 보는 내꼴이 우습다.

https://seekingalpha.com/ 에 내가 보유한 주식 종목이나 빅테크 기업 등에 대한 정보를 기록할 수 있다.

 

퇴직하고 나서 미국주식 주린이가 미친듯이 영상보면서 분석한다고 분석한 종목이 아닌 종목을 호기심으로 매수했다가 30% 이상 하락을 경험하고 나니 맨붕이다.

그냥 유료결제를 해서 정보를 봤으면 일찍 판단했을까? 싶은 마음이 든다. 200만원 매수해서 손실 본 금액이 이미 1년 유료결재 금액을 넘어서 버렸다.

 

이렇게 주식 종목의 건강도 체크를 해준다고 표시해준 종목이 LPTH 종목이다.

위 차트에서 최고의 고점에서 잡아서 주가가 수직 하방중이다.

주가는 이렇게 떨어지고 있는데도 불구하고 여전히 Awesome! 이랜다. 우라질~~~

 

이렇게 된 원인에는 미국 10년물 국채 금리가 계속 상승하고 있다. 빅테크주식도 하락하지만 중소형주에는 더 큰 악재다.

예상과 달리 강세를 보인 고용 지표가 기준금리 인하 기대감이 약화하면서 주식 시장이 매우 좋지 않았다.

 

주가 맵은 https://finviz.com/map.ashx?t=sec 에서 볼 수 있다.

 

주식 오래한 친구에게 문의해보니 주가가 하락할 때 많이 떨어지는 종목을 매도하고 적게 떨어지는 종목을 보유해야 한다고 한다. 나는 강추 2종목을 매수했다가 별로 떨어지지 않은 1종목을 매도하고 많이 떨어진 종목을 보유하고 있다.

매도할 기회를 놓치니까 손절할 기회가 없는 것 같다. 아니 손절했다가 다시 반등하거나 seekingalpha 사이트가 강추한 이유를 유료가 아니라 제대로 파악할 수 없어서 그런 것인가 하며, 내심 기대하는 심리라고 봐야 한다.

 

얼마전에 매수했던 종목이 10% 떨어지길래 매도했더니, 그날 장 막판까지 주가가 많이 회복되었고, 그 다음날 20% 상승, 그 다음날 10% 상승으로 시작하는 걸 경험했기에 이번에는 버텨보자 하다가 심하게 손실을 보게 되었다.

seekingalpha 가 첫달에는 5달러 정도에 유료 사이트 내용을 볼 수 있게 해주겠다고 하고 1년에 300달러 정도 유료결제를 유도하는 정책을 하고 있더라.

아직 미국주식 제대로 파악도 안되어서 물량을 많이 실었다가는 큰 낭패를 볼 수 있기에 조심스럽게 접근하고 있는데도 어렵다.

 

 

아직 분석 제대로 할 줄 모르고 무료라서 숨겨진 정보는 볼 수가 없다.

애널리스트는 LPTH 종목의 주가를 4달러, 5달러로 추천한 건 게시글을 찾아서 봤다.

현재 장이 전체적으로 안좋아서 떨어진 것인지? 잘못 매수해서 회복이 어려운 것인지 판단할 수가 없어서 미국주식 전문가 사이트에 분석 요청을 했는데 도움을 받는다면 큰 도움이 될 거 같다.

 

 

보유한 주식수와 비중이 나오고 매수한 날짜 정보가 나온다. 이런 기능은 좋은 거 같다.

매도해 버린 종목에 대한 관리는 어떻게 되는지 모르겠다.

실수를 통해서 배우는 것도 기록해서 밑거름이 되도록 하련다.

seekingalpha.com 사이트 분석하는 방법을 구글 검색으로 더 찾아봐야겠다.

728x90
블로그 이미지

Link2Me

,
728x90

jQuery Mobile 로 된 오래된 코드를 최신의 jQuery 로 적용했더니 화면이 깨지고 엉망이다.

이를 해결하기 위한 방법이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html> 
<html> 
<head> 
<title><?php echo $hostName;?></title>
<meta charset="utf-8" />     
<meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0, minimum-scale=1.0,user-scalable=no"/>
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="expires" content="-1" />
<meta http-equiv="pragma" content="no-cache" />
<link rel="shortcut icon" href="./images/icon72.png">
<link rel="apple-touch-icon" href="./images/icon57.png">
<link href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css" rel="stylesheet" type="text/css" />
<link href="css/mWebStyle.css" rel="stylesheet" type="text/css" />
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://code.jquery.com/jquery-migrate-3.5.2.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<script src="js/jsencrypt.min.js"></script>
<script src="js/mWebScript.js"></script>
 

 

별도 코드가 추가될 수 있기 때문에 하단에 </head> 태그를 생략했고 개별 파일에서 추가했다.

728x90
블로그 이미지

Link2Me

,
728x90

사이버 보안주 센티넬원의 전망을 정리한 자료이다.

 

https://seekingalpha.com/symbol/S

 

 

728x90
블로그 이미지

Link2Me

,
728x90

 

재무상태표 : 기업의 재무상태를 나타내기 위해 일정시점현재의 자산, 부채, 자본을 나타내는 보고서

자산 = 부채 + 자본

자산 : 기업이 소유하고 있는 재화나 채권으로 금전적 가치가 있는 것

부채 : 타인 자본 = 기업이 미래 시점에 타인에게 지급해야 할 채무 (매입채무, 선수금 등)

자본 : 기업 소유의 자산총액에서 타인에게 지급할 부채총액을 차감한 잔액 = 자기자본(자본금, 자본잉여금, 이익잉여금)

 

재무제표(=기업의 건강진단서)는 주식 투자의 절대적인 지표가 아니다!

재무제표의 한계 : 기업의 미래를 알 수 없다.

 

손익계산서 : 매출액, 영업이익, 당기순이익

 

- 매출실적이 매년 증가하는지 살펴봐라.

- 적자에서 흑자 전환이 되는 기업은 눈여겨 보라.

- 누적 적자가 있는 기업이 신사업을 한다면, 웃기는 짬뽕 짓이다.

- 누적 적자가 있는 기업은 쳐다보지 마라.

 

현금흐름표

- 영업활동으로 인한 현금 흐름 : 매출채권, 매입채무, 재고자산

- 투자활동으로 인한 현금 흐름 : 유형자산의 투자, 유형자산의 매각, 주식의 취득, 주식의 매각

- 재무활동으로 인한 현금 흐름 : 차입, 차입 상환, 배당금 지급

 

재무제표는 과거 자료이고 미래 성장성은 반영하지 못한다.

재무제표상의 성장성, 수익성, 안전성 등은 이미 현재 주가에 반영되어 있다.

 

욕망의 늪에 빠지지 마라. 감정투자하지 마라.

감정에 휘둘리는 것은 우리가 자기 객관화를 못한다는 것이다.

자기자신에 대한 믿음이 없다는 것은 내 투자실력이 지금 그거밖에 안된다는 것이다.

대부분의 사람들은 개미가 아니라 불나방, 하루살이 투자를 하고 있다.

사람들은 자책과 반성을 구분하지 못한다. 내가 반성한다고 생각하는 사람들 대부분은 자책을 한다. 그게 현재가 마음에 안드니까, 미래가 불안하니까 계속 과거의 자신을 공격한다. 자책의 악순환에 빠질 수 있다.

1. 자책하지 마라. 2. 남탓하지 마라.

준비가 된 사람은 계속 수익을 낸다. 남탓을 하는 건 본인을 돌아보지 않겠다는 얘기다. 본인을 돌아보지 않겠다는 건 자기객관화가 안되는 거고, 그럼 공부하지 않겠다는 거다.

지금 당장 조그마한 것이라도 바꿔봐라.

 

 

손대면 안되는 주식

1. 시가총액 300억 미만 주식은 쳐다보지 마라.

2. 본인 투자금액의 20 ~ 30배의 일일 거래금액이 되어야 한다.

    1억을 투자했는데 하루 거래금액이 2억도 안된다면 문제가 있는 주식이다.

3. 매출이 줄어들고, 영업이익 적자가 3년 이상된 종목은 쳐다보지 마라.

4. 조사4국, 탈세, 소송, 경찰, 검찰, 불성실공시, 대주주변경(빈도), 횡령, 배임

 

유동비율 = 유동자산 ÷ 유동부채 → 유동비율이 100%가 넘는지 아닌지만 보라.

유동부채 : 1년안에 갚아야 할 의무가 있는 부채

유동자산 : 현금, 예금, 외상판매대금, 재고자산 등 단시간 내에 자금화 할 수 있거나 바로 사용할 수 있는 자산

당장 눈 앞에 닥친 부채를 갚지 못하면 도산할 가능성이 높다.

 

자기자본비율 = 순자산 ÷ 자산

자기자본비율이 높아도 단기적으로 자금 부족 상태가되면 기업은 도산할 수 있다.

자기자본비율은 기업의 중장기적인 안전성을 나타낸다.

 

 

728x90
블로그 이미지

Link2Me

,
728x90

미국 주식 입문 초보로 영상을 보다보니 tradingview 에서 스토캐스틱 설정값을 어떻게 설정하는지가 궁금해서 문의하여 적어둔다.

 

 

 

728x90
블로그 이미지

Link2Me

,
728x90

계피는 하루 1티스푼 이상을 먹지 말아야 한다. 쿠마린은 과다 섭취시 간에 부담을 준다.
계피 섭취 후 잇몸이 붓거나 뜨겁고 가려운 증상 있다면 계피 드시기 않는 것이 좋다.
계피는 혈액순환을 원활하게 하고, 열을 만들어 몸을 따뜻하게 한다.
계피의 폴리페놀 성분이 혈당을 조절해 고혈압에 효과적이며 몸 안에서 인슐린 작용을 해 당뇨를 개선한다.
설사를 멎게하고 배에 가스차는 증상을 치료해주는 효능이 있다.
계피에는 살충효과가 있어서 계피가루를 태우면 모기, 집먼지 진드기 같은 해충이 사라지게 된다.
계피에는 방향성 성분이 풍부하기 때문에 계피로 양치를 하면 구취가 제거되고 구강내 세균번식을 억제한다. 
또한 계피는 충치예방에도 효과가 있다.
소화기관 뿐만 아니라 자궁을 따뜻하게 만들어 여성 질환에 좋다.빈혈에 좋으며 자궁을 튼튼하게 해 생리통, 생리 불순에 효과적이다.

생강은 첫째, 비만과 당뇨, 심장병의 위험도를 낮추고 전반적인 사망률을 감소시켜주고 있음이 밝혀졌다.

줄기 15~30g, 껍질 5~10g에 물 1.5~1.8리터를 넣고 약 30분 정도 끓여서 수시로 마시면 된다.

가시오가피에 함유되어 있는 아칸토사이드는 뼈의 건강을 증진시켜주며 골다공증 및 관절염 증상 완화에 도움이 된다.
가시오가피는 눈의 피로를 풀어주는 효능이 있어 집중력 향상 및 시력이 저하되는 것을 예방해 준다.
가시오가피에 함유되어 있는 치사노사이드 성분은 간을 건강하게 할 뿐만 아니라 간에서 생기는 독소를 해독하는 작용을 한다.
따뜻한 성질을 가졌기 때문에 평소 몸에 열이 많은 사람이 먹으면 설사나 구토, 메스꺼움 등의 증상이 나타날 수 있다.

 

가시오갈피를 섭취한 후 피부발진, 두통, 소화불량, 설사 등의 부작용이 나타난다면 자신에게 맞지 않는 것이므로 반드시 전문의와 상의하는 것이 좋다.

728x90
블로그 이미지

Link2Me

,
728x90

 

로보틱 프로세스 자동화(RPA, Robotic Process Automation) 플랫폼을 제공하는 글로벌 기업이다.

UiPath는 소프트웨어 로봇을 사용하여 반복적이고 규칙적인 작업을 자동화하여 기업의 효율성을 높이고 인적 자원이 더 중요한 업무에 집중할 수 있도록 돕는다.

주요 특징 및 장점
ㅇ 사용자 친화적인 인터페이스
    - 비개발자도 이해하기 쉬운 드래그 앤 드롭 방식의 워크플로우 디자이너 제공.
    - 복잡한 프로세스를 쉽게 시각적으로 구성할 수 있음.
ㅇ 다양한 통합 가능성
    - 기존의 ERP, CRM, 웹 애플리케이션 등 다양한 시스템과 통합이 가능.
    - API 없이도 UI 기반으로 다양한 애플리케이션과 상호작용 가능.
ㅇ 확장 가능한 자동화
    - 데스크톱, 클라우드, 서버 환경에서 확장 가능한 자동화 가능.
    - 소규모 팀부터 대규모 조직까지 유연하게 적용 가능.
ㅇ AI 통합
    - 문서 이해(Documents Understanding), 자연어 처리(NLP), 컴퓨터 비전 등의 AI 기술을 통합하여 지능형 자동화 제공.
ㅇ 커뮤니티와 학습 지원
    - 무료로 학습할 수 있는 UiPath Academy 제공.
    - 사용자 커뮤니티 포럼과 리소스 풍부.

 

 

UiPATH가 생성형 AI의 성장세와 코딩과 같은 분야에서 AI가 빠르게 발전하는 상황을 활용하지 못하는 것은 큰 위험이다.

회사의 미래에 대한 심각한 위협에도 불구하고, UiPATH는 적당한 가치평가, 많은 현금 보유액, 긍정적인 현금 흐름, 자사주 매입 등에 힘입어 괜찮은 성과를 거둘 것으로 예상된다.

투자자들은 여전히 경쟁의 중요성과 세그먼트 전체 수요 역풍에 대해 고민하고 있을 가능성이 크다.

AI Agent 시장은 아직 초기 단계이지만 앞으로 몇 년 안에 폭발적으로 성장할 것으로 예상된다.

 

썰물이 빠지고 나서야 비로소 누가 발가벗고 수영을 했는지 알 수 있다.

실속없는 주식에 투자했던 투자자들은 썰물이 빠져나가면 그때 다 수익률이 박살나고 쓸려나간다.

단단하게 투자를 하고 있는게 지금 내가 맞는가?

한번 더 점검을 해 보셔야 되는 타이밍이다.

 

728x90
블로그 이미지

Link2Me

,
728x90

물가상승률이 많이 내려왔지만, 여전히 목표치인 2%에서 멀다.

PCE는 여전히 3%에 더 가깝다.

12월 FOMC는 25bp를 내려 금리 인하 사이클의 첫번째 단계를 마무리할 것이다.

 

11월 소비자물가(CPI)는 예상에 부합했고, 생산자물가(PPI)는 조류독감으로 치솟은 계랸 값을 빼면 나쁘지 않다.

지난주 발표된 미국의 11월 실업률이 4.246% 높아진 것도 고려해야 할 요인이다.

 

일단 인플레이션이 식으면 기준금리는 낮아지고 채권 가격은 상승할 수 있다.

정확히 언제 그런 일이 일어나는지는 채권포트폴리오의 Duration을 연장(장기물매수)하여 대비하는 것보다 중요하지 않다. 즉 FED가 금리를 내릴 것이기 때문에 장기 채권을 사라는 얘기다.

 

브로드컴의 약진은 TSMC, ARM, 마이크론에는 호재로 작용했다. 하지만 엔비디아와 AMD에게는 악재였다.

2024년 브로드컴의 매출은 500억달러인데 AI 매출은 100억달러 정도다.

브로드컴 CEO는 2027년 AI 매출 600억달러 ~ 900억 달러로 전망했다.

모건스탠리는 애플에 대해 "2025년으로 향하는 우리의 최고 선택으로 남을 것"이라며 목표주가 273달러를 제시했다.

728x90
블로그 이미지

Link2Me

,
728x90

Rocky Linux 9버전에서는 기본으로 PHP 8.X가 설치되어 있는데 기존에 개발한 코드가 PHP 7.4 기반이라 PHP7.4를 설치하는 스크립트를 시행착오를 겪어가면서 거의 완벽에 가까운 스크립트를 작성했다.

스크립트 구성후 개발한 코드로 동작시켜 보니 RSA 암호화/복호화가 제대로 동작되지 않아서 원인 찾느라고 쌩쇼를 했다.

 

#############################################
######### RockyOS 9.5 PHP 7.4 설치 ##########
#############################################
# 본 스크립트는 반드시 관리자 권한에서 실행해야 한다.
# openssl 버전 확인 => TLS 1.3을 지원하더라.
openssl version
 
## 현재 설치된 PHP 버전 확인
dnf module list php
 
Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled
 
 
dnf -y install expat-devel
 
## 설치확인
dnf list installed | grep MariaDB
rpm -qa | grep MariaDB
 
 
# 설치되어 있는 PHP 모듈 확인 방법
php -m
 
# 시스템 업데이트
sudo dnf -y update
 
sudo dnf -y install wget unzip mc git nmap
 
# SSL 관련 패키지 설치 확인
sudo dnf -y install openssl openssl-devel
 
# 1. Apache 설치
sudo dnf install httpd -y
 
# 2.EPEL 및 Remi 저장소 설치
sudo dnf -y install epel-release
sudo dnf -y install https://rpms.remirepo.net/enterprise/remi-release-9.rpm
 
# 3.PHP 모듈 재설정 및 Remi 저장소 활성화
sudo dnf module reset php
sudo dnf module enable php:remi-7.4
 
# 4.PHP 7.4 및 필요한 확장 모듈 설치
sudo dnf -y install php php-cli php-fpm php-curl php-mysqlnd php-gd php-opcache php-zip php-intl php-common php-bcmath 
sudo dnf -y install php-imagick php-xmlrpc php-json php-readline php-redis php-mbstring php-apcu php-xml php-dom php-redis 
sudo dnf -y install php-memcached php-memcache php-devel php-openssl 
sudo dnf -y install mod_ssl openssh
sudo dnf -y install ImageMagick ImageMagick-devel
 
# PHP 7.4 에서는 설치 필요. PHP 8.X에서는 에러 표시함.
sudo dnf -y install php-mcrypt
 
# 5. PHP 버전 확인
php -v
 
 
# Apache 버전 확인
httpd -v
 
 
# PHP와 웹 서버 간 통신이 차단될 수 있으니 SELinux 설정 확인
sudo setsebool -P httpd_can_network_connect 1
 
 
# 서비스 시작
sudo systemctl start php-fpm
sudo systemctl start httpd
 
# 서비스 활성화
sudo systemctl enable php-fpm
sudo systemctl enable httpd
 
systemctl stop httpd
systemctl restart httpd
systemctl status httpd
 
#####################################################################
## httpd.conf 파일 수정
#####################################################################
vi /etc/httpd/conf/httpd.conf
ServerName localhost
 
DocumentRoot "/var/www/html"
 
<Directory "/var/www/html">
    Options +FollowSymLinks -Indexes
    AllowOverride All
    Require all granted
    <LimitExcept GET POST>
      Order deny,allow
      Deny from all
    </LimitExcept>
</Directory>
 
<IfModule dir_module>
    DirectoryIndex index.html index.php index.jsp
</IfModule>
 
<IfModule mime_module>
    TypesConfig /etc/mime.types
    #AddType application/x-gzip .tgz
    #AddEncoding x-compress .Z
    #AddEncoding x-gzip .gz .tgz
    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz
    AddType application/x-httpd-php .php .html .do
    AddType application/x-httpd-php-source .phps
    AddType text/css .css
    AddType text/javascript .js
    #AddHandler cgi-script .cgi
    #AddHandler type-map var
    #AddOutputFilter INCLUDES .shtml
</IfModule>
 
ErrorDocument 400 /error.php
ErrorDocument 401 /error.php
ErrorDocument 402 /error.php
ErrorDocument 403 /error.php
ErrorDocument 404 /error.php
ErrorDocument 405 /error.php
ErrorDocument 408 /error.php
ErrorDocument 500 /error.php
ErrorDocument 501 /error.php
ErrorDocument 502 /error.php
ErrorDocument 503 /error.php
 
# 보안 검증 통과를 위해 반드시 서버 정보 노출 방지 해야 함.
ServerTokens Prod
ServerSignature Off 
 
TraceEnable Off
 
# Apache HTTPOXY 취약점 방지
RequestHeader unset Proxy early
 
저장하고 나온다.
 
#####################################################################
# php.ini 환경 설정
#####################################################################
vi /etc/php.ini
short_open_tag = On
;경로 기반의 공격 방지
cgi.fix_pathinfo=0
 
;PHP 버전 정보 노출 방지(Hide PHP Version Number)
expose_php = Off
 
post_max_size = 20M  ;// 8M 으로 되어 있었음.
upload_max_filesize = 18M ;// 기본 2M 으로 되어 있었음
 
date.timezone ="Asia/Seoul"
 
 
;PHP에서 세션은 일단 생성 된 뒤에, 가비지 콜렉터 관리로직에 의해 소멸된다.
session.gc_probability = 1
session.gc_divisor = 1
;이값이 100이면 1/100 즉 1%의 확률로 가비지콜렉션이 실행된다.
;1이면 정확하게 유효기간이 넘은 데이타가 삭제될 것이다.
session.gc_maxlifetime = 3600
 
# 저장하고 나온다.
 
# Apache 서버 재기동
systemctl restart httpd
 
# 서버 정보 확인
# ip addr 로 IP 주소 정보를 확인하고 해당 IP주소로 대체하여 입력
curl -192.168.1.20
 
# Apache 라는 서버 정보가 보인다. 이것마저 방지하고자 한다면....
dnf install mod_security
 
vi /etc/httpd/conf/httpd.conf
<IfModule security2_module>
   SecRuleEngine on
   ServerTokens Full
   SecServerSignature "Link2me"
</IfModule>
 
저장하고 나온다.
 
# Apache 서버 재기동
systemctl restart httpd
 
# 서버 정보 확인
curl -192.168.1.20
 
#####################################################################
sudo systemctl start httpd
sudo systemctl enable httpd
sudo systemctl start php-fpm
sudo systemctl enable php-fpm
 
# PHP-FPM 구성
vi /etc/php-fpm.d/www.conf
user = apache
group = apache
 
listen = /run/php-fpm/www.sock
 
listen.owner = apache
listen.group = apache
listen.mode = 0660
 
;shift + G 눌러서 제일 하단으로 이동하여
php_value[opcache.file_cache] = /var/lib/php/opcache  ; 주석만 제거
 
저장하고 나온다.
 
vi /etc/httpd/conf.d/php-fpm.conf
 
<FilesMatch \"\.php$\">
    SetHandler \"proxy:unix:/run/php-fpm/www.sock|fcgi://localhost/\"
</FilesMatch>
 
확인하고 틀리면 수정/저장하고 빠져나온다.
 
sudo systemctl restart httpd
sudo systemctl restart php-fpm
 
#####################################################################
# 반드시 추가구현해야 문제없이 동작한다.
cd /var/www/html/
vi .htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ error.php?/$1 [QSA,PT,L]
</IfModule>
 
 
## 보안설정
sudo chmod 640 /etc/httpd/conf/httpd.conf
sudo chown root:root /etc/httpd/conf/httpd.conf
sudo chmod 640 /etc/php.ini
sudo chown root:root /etc/php.ini
 
sudo chown -R apache:apache /var/www/html
sudo chmod -755 /var/www/html
 
####################################################################################
# CentOS7 과 달리 chmod 644 를 지정해줘야 제대로 동작되는 걸 확인했다.
mkdir -/home/rsa/key/
cd /home/rsa/key/
openssl genrsa -out rsa_pri.pem 2048
openssl rsa -pubout -in rsa_pri.pem -out rsa_pub.pem
# Rockey Linux 9 에서 읽기가 관리자권한만 가능하게 되어 있어서 수정해서 해결했다.
# 이 한줄 때문에 숱한 버그 찾기 끝에 해결했다.
chmod 644 rsa_pri.pem
 
# 세션이 저장되는 디렉토리 퍼미션 지정
sudo chmod 777 -/var/lib/php/session
 
sudo chmod 1733 /var/lib/php/session
sudo chown apache:apache /var/lib/php/session
 
# 세션 확인
cd /var/lib/php/session
ll
 
# Clear Old Sessions
sudo rm -rf /var/lib/php/session/*
 
####################################################################################
# 방화벽 데몬 시작
systemctl start firewalld
 
# 서버 부팅 시 firewalld 데몬 자동 시작 설정
systemctl enable firewalld
 
firewall-cmd --permanent --add-service=http 
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-service=mysql
firewall-cmd --permanent --zone=public --add-port=3306/tcp
 
firewall-cmd --permanent --zone=public --add-port=8000/tcp
firewall-cmd --reload
firewall-cmd --list-all
 
#######################################################################
 
cd /var/www/html
wget https://files.phpmyadmin.net/phpMyAdmin/5.2.1/phpMyAdmin-5.2.1-all-languages.zip
unzip phpMyAdmin-5.2.1-all-languages.zip
chown -R apache:apache phpMyAdmin-5.2.1-all-languages
mv phpMyAdmin-5.2.1-all-languages pma
cd pma
cp -rp config.sample.inc.php  config.inc.php
 
# 환경 설정
vi config.inc.php
 
$cfg['blowfish_secret'= 'qtdRoGmbcr]0s)r$9b_JUnoGmbcbcr]0s)r$9b_JUnoGmr]0s)r$9b{~Xz'// 임의의 값 설정
$cfg['Servers'][$i]['host'= 'localhost';
$cfg['Servers'][$i]['compress'= true;
$cfg['TempDir'= '/tmp';
 
 
###############################
###### composor 설치 #####
###############################
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
composer -V
export COMPOSER_ALLOW_SUPERUSER=1
composer -V
echo "export COMPOSER_ALLOW_SUPERUSER=1" >> ~/.bashrc
cat ~/.bashrc | grep export
 
composer require phpoffice/phpspreadsheet
 
composer require phpmailer/phpmailer
####################################################################################
# 기본 버전을 설치하고 싶다면 아래와 같이 제거 후에 재설치
dnf remove php
 
# 제거후에는 반드시 Reset 해야 한다.
dnf module reset php
 
# 8.2로 활성화
dnf module enable php:8.2
 
# 재설치 진행
dnf install php
####################################################################################
# 서버가 지원하는 TLS 버전 확인 코드
 
<?php
  $ch = curl_init('https://www.howsmyssl.com/a/check'); 
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
  $data = curl_exec($ch); 
  curl_close($ch); 
  $json = json_decode($data); 
  echo "<h1>Your TLS version is: " . $json->tls_version . "</h1>\n";
?>
####################################################################################
 

 

위 환경 설정 httpd.conf 및 php.ini 에는 보안검증 받으면서 지적사항 해결에 사용한 것도 같이 포함되어 있다.

728x90
블로그 이미지

Link2Me

,
728x90

Rocky Linux에서 사용되는 dnf는 "Dandified Yum"의 약자로, 패키지 관리 도구이다.
Rocky Linux와 같은 RHEL 계열 리눅스 배포판에서 사용되며, 시스템 패키지(소프트웨어)를 설치, 제거, 업데이트, 검색, 관리하는 데 사용된다. 이전의 Yum(Yellowdog Updater, Modified)을 대체하는 도구로, 더 빠르고 강력하며 개선된 의존성 처리 및 성능을 제공한다.


DNF의 주요 특징
- 의존성 해결 개선: 패키지 설치 시 의존성 충돌을 더 정확하고 효율적으로 처리.
- 빠른 성능: C언어와 Python3 기반으로 작성되어 더 빠른 패키지 처리 가능.
- 확장성: 플러그인을 통해 기능 추가가 용이.
- 메모리 사용 감소: 더 적은 메모리로 효율적으로 실행.
- 리포지토리 관리: 여러 리포지토리를 쉽게 설정하고 관리.

DNF의 주요 명령어
- dnf install <패키지>: 패키지 설치
- dnf remove <패키지>: 패키지 제거
- dnf update: 시스템 전체 패키지 업데이트
- dnf upgrade: 업데이트와 비슷하지만, 더 새로운 버전으로 업그레이드
- dnf search <키워드>: 특정 패키지 검색
- dnf list: 설치 가능한 패키지 목록 표시
- dnf info <패키지>: 패키지 정보 표시
- dnf clean all: 캐시 파일 정리

 

Rocky Linux 9.5 에서 설치 테스트한 스크립트이다.

################################
##### MariaDB 10.11 버전 설치 #####
################################
 
vi /etc/yum.repos.d/MariaDB.repo
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.11/rhel9-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
 
 
# DNF 패키지 관리자에서 사용할 수 있는 저장소의 목록을 출력하고, MariDB 저장소를 확인
dnf repolist
 
# MariaDB 설치
dnf -y install MariaDB-server MariaDB-client
 
# mariadb 부팅 시 자동 시작 설정
systemctl enable mariadb
 
# mariadb 시작
systemctl start mariadb
 
# mariadb 상태 확인
systemctl status mariadb
 
# MariaDB 설정
mariadb-secure-installation
 
비밀번호 설정
 
# MariaDB 프로세스 확인 (둘중 하나 실행)
ps -ef | grep mysql
ps -ef | grep mariadbd
 
vi /etc/my.cnf.d/server.cnf
[mysqld]
collation-server = utf8_general_ci
init-connect='SET NAMES utf8'
character-set-server = utf8
 
vi /etc/my.cnf.d/mysql-clients.cnf
[mysql]
default-character-set=utf8
[mysqldump]
default-character-set=utf8
 
# 서비스 재시작
systemctl restart mariadb
 
mysql -u root -p
status
# 설치는 여기까지 하면 완료다. 아래 사항은 패스워드 인증방식에 대한 사항이다.

use mysql;
select * from global_priv;
select host,user,password,plugin from user;
 
# (10.4 버전 이상)이전 패스워드 인증방식으로 설정하기 ==> 패스워드 입력 방식
ALTER USER root@localhost IDENTIFIED VIA mysql_native_password USING PASSWORD("비밀번호");
flush privileges;
 
# unix_socket 인증방식으로 설정하기 ==> root 권한으로 접속 시 비밀번호 없이 인증
ALTER USER root@localhost IDENTIFIED VIA unix_socket;
flush privileges;
select host,user,password,plugin from user;
 
# 원격은 무조건 패스워드 인증으로만 접근이 가능하다.
 
#######################################################################
####### 실제 적용 예제 ######
#######################################################################
mariadb -u root -p
 
use mysql;
create user codefox@localhost identified by 'codefoxfull!!';
grant all privileges on orgChart.* to codefox@localhost;
flush privileges;
 
-- DB 생성
create database orgChart default character set utf8;
use orgChart;
 
-- 파일 업로드
source orgChart.sql;
 
 
#######################################################################
# DB 백업
mysqldump -uroot ---databases orgChart > orgChart.sql
 
# MariaDB 환경설정 관리 경로
ls -al /etc/my.cnf.d/
 
#######################################################################
# MariaDB 설치 경로 확인
cd /var/lib/mysql
 
############################
### root 패스워드 분실 복구 ####
############################
# 콘솔 창을 2개 준비하여 작업한다.
# 먼저 mariadb 서비스 중지한다.
systemctl stop mariadb
 
# 상태 확인
systemctl status mariadb
 
# 콘솔 A 창에서 확인한다.
ps -ef | grep mysql
 
# 콘솔 B창에서 DB 실행
sudo mysqld_safe --skip-grant-tables &
 
# 콘솔 A창에서 확인
ps -ef | grep mysql
 
# 콘솔 A창에서 비밀번호 없이 접속하여 패스워드 변경
mysql -u root 
 
-- 저장된 인증방식을 비활성화하기 위해 먼저 실행한다.
flush privileges;
 
-- 비밀번호 변경
grant all privileges on *.* to 'root'@'localhost' identified by '비밀번호';
flush privileges;
exit
 
# 콘솔 B창에서 Enter를 눌러 백그라운드 모드에서 빠져나온다.
 
# 콘솔 A창에서 실행되는 DB 모두 죽이기
ps -ef | grep mysql
kill -9 PID번호
를 해서 하나 하나 mysql 데몬을 전부 죽인다.
 
# 실행되는 mysql 프로세스가 없는지 확인한다.
ps -ef | grep mysql
 
# MariaDB 시작
systemctl start mariadb
 
# 접속 테스트
mysql -uroot -p
 

 

 

 

728x90
블로그 이미지

Link2Me

,
728x90

VMWare 를 이용하면 Windows 에 가상머신으로 Linux를 설치할 수 있다.

VirtualBox 와 VMWare 를 이용하면 된다.

 

VMWare 에 Rocky Linux 9 버전을 설치하는 과정을 캡쳐한 이미지이다.

 

먼저 Rocky-9.5 버전의 DVD ISO 파일을 받아둔 경로를 선택한다.

 

설치할 경로를 설정한다.

 

DISK 사이즈를 정한다.

 

Hardware 구성을 한다. IPTIME 공유기 하단에서 Private IP Address 를 할당받기 때문에 NetworkAdapter 를 Bridged 모드로 변경하고 메모리는 4GB 로 변경했다.

 

실제 설치과정을 시작하는 첫번째 화면이다.

 

 

언어는 한국어로 선택했다.

 

빨간색으로 된 부분을 설정해야 하고, 네트워크와 호스트 이름을 설정해야 한다.

 

root 비밀번호를 설정하고 아래 그림의 빨간줄을 선택하지 않으면 SSH root 로그인은 안된다.

 

네트워크 부분을 설정한다. 설정하지 않으면 자동으로 DHCP(유동 IP주소) 방식이 기본이다.

항상 고정 IP주소로 변경하려면 수정해야 한다.

 

 

 

 

 

사용자 설정을 안해서 사용자 설정을 하도록 요구해서 사용자ID와 비밀번호를 설정했다.

 

 

SSH 콘솔 접속을 하기 위한 설정이 되었는지 확인하고 추가 조치를 한다.

 

 

nmtui 를 입력하면 팝업창이 나온다.

 

여기까지 하고 나서 ping 테스트를 해본다.

ping 168.126.63.1

정상이면 네트워크 설정은 된 것이다.

 

#############################################
######### RockyOS 9 버전 확인 #################
#############################################
cat /etc/redhat-release
 
# 네트워크 설정
# 자동완성 기능을 이용하여 네트워크 초기 설정된 파일명을 찾는다.
# IP주소를 고정으로 하기 위한 설정이다.
# /etc/NetworkManager/system-connections 파일(RHEL 계열 9 시리즈부터)
vi /etc/NetworkManager/system-connections/ens 
# 까지 입력하고 TAB을 누르면 자동으로 파일이 찾아진다.
 
[connection]
id=ens160
uuid=4afae337-7442-357f-bb10-abae90f2119e
type=ethernet
autoconnect-priority=-999
interface-name=ens160
timestamp=1732491117
 
[ethernet]
 
[ipv4]
address1=192.168.1.20/24,192.168.1.100
dns=168.126.63.1;168.126.63.2;8.8.8.8;
method=manual
 
[ipv6]
addr-gen-mode=eui64
method=auto
 
[proxy]
 
:wq(저장)하고 나온다.
systemctl restart NetworkManager
 
 
ping 168.126.63.1
# ping 테스트를 해보면 네트워크가 동작되는지 확인할 수 있다.
 
# DNS 설정
vi /etc/resolv.conf
nameserver 168.126.63.1
nameserver 168.126.63.2
nameserver 8.8.8.8
 
# selinux 설정
vi /etc/sysconfig/selinux
SELINUX=disabled
로 변경하고 저장한다.
 
##########################################################################
#RockeyOS update
dnf -y update
 
##########################################################################
# 방화벽 설정(기본 설치되어 있다)
dnf -y install firewalld
 
# 방화벽 데몬 시작
systemctl start firewalld
 
# 서버 부팅 시 firewalld 데몬 자동 시작 설정
systemctl enable firewalld
 
firewall-cmd --permanent --add-service=http 
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-service=mysql
firewall-cmd --permanent --zone=public --add-port=3306/tcp
 
firewall-cmd --permanent --zone=public --add-port=8000/tcp
firewall-cmd --reload
firewall-cmd --list-all
 
##########################################################################
# mc 설치
dnf -y install mc
 
# 열린포트 확인
netstat -nltp
 

 

728x90
블로그 이미지

Link2Me

,
728x90

MariaDB 10.6 설치 스크립트 및 root 비밀번호 복구 방법 등 전반에 대한 사항이다.

 

################################
##### MariaDB 10.6 버전 설치 #####
################################
 
vi /etc/yum.repos.d/MariaDB.repo
# MariaDB 10.6 CentOS repository list
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.6/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
 
sudo yum makecache fast
yum -y install mariadb-server mariadb-client
 
# mariadb 부팅 시 자동 시작 설정
systemctl enable mariadb
 
# mariadb 시작 (둘 중 하나 실행)
systemctl start mariadb
service mariadb start
 
# mariadb 상태 확인
service mariadb status
 
# MariaDB 설정
mariadb-secure-installation
 
 
# MariaDB 프로세스 확인 (둘중 하나 실행)
ps -ef | grep mysql
ps -ef | grep mariadbd
 
vi /etc/my.cnf.d/server.cnf
[mysqld]
collation-server = utf8_general_ci
init-connect='SET NAMES utf8'
character-set-server = utf8
 
vi /etc/my.cnf.d/clients.cnf
[mysql]
default-character-set=utf8
[mysqldump]
default-character-set=utf8
 
service mariadb restart
mysql -u root -p
status
quit
 
# 서비스 재시작
systemctl restart mariadb
 
mariadb -u root -p
use mysql;
select * from global_priv;
select host,user,password,plugin from user;
 
# (10.4 버전 이상)이전 패스워드 인증방식으로 설정하기 ==> 패스워드 입력 방식
ALTER USER root@localhost IDENTIFIED VIA mysql_native_password USING PASSWORD("비밀번호");
flush privileges;
 
# unix_socket 인증방식으로 설정하기 ==> root 권한으로 접속 시 비밀번호 없이 인증
ALTER USER root@localhost IDENTIFIED VIA unix_socket;
flush privileges;
select host,user,password,plugin from user;
 
# 원격은 무조건 패스워드 인증으로만 접근이 가능하다.
 
#######################################################################
####### 실제 적용 예제 ######
#######################################################################
mariadb -u root -p
 
use mysql;
create user codefox@localhost identified by 'codefoxfull!!';
grant all privileges on orgChart.* to codefox@localhost;
flush privileges;
 
-- DB 생성
create database orgChart default character set utf8;
use orgChart;
 
-- 파일 업로드
source orgChart.sql;
 
 
#######################################################################
# DB 백업
mysqldump -uroot ---databases orgChart > orgChart.sql
 
# MariaDB 환경설정 관리 경로
ls -al /etc/my.cnf.d/
 
#######################################################################
# MariaDB 설치 경로 확인
cd /var/lib/mysql
 
############################
### root 패스워드 분실 복구 ####
############################
# 콘솔 창을 2개 준비하여 작업한다.
# 서비스 중지
systemctl stop mariadb
 
# 상태 확인
systemctl status mariadb
 
# DB 실행
sudo mysqld_safe --skip-grant-tables &
 
# 다른 콘솔창에서 확인
ps -ef | grep mysql
 
# 비밀번호 없이 접속하여 패스워드 변경
mysql -u root 
 
-- 저장된 인증방식을 비활성화하기 위해 먼저 실행한다.
flush privileges;
 
-- 비밀번호 변경
grant all privileges on *.* to 'root'@'localhost' identified by '비밀번호';
flush privileges;
exit
 
# 실행되는 DB 모두 죽이기
ps -ef | grep mysql
kill -9 PID번호
를 해서 실행된 창을 전부 죽인다.
 
# 실행되는 mysql 프로세스가 없는지 확인한다.
ps -ef | grep mysql
 
systemctl start mariadb
 
# 접속 테스트
mysql -uroot -p
비밀번호
 

 

 

위 스크립트 파일 첨부

CentOS7 MariaDB10.6.txt
0.00MB

 

728x90
블로그 이미지

Link2Me

,
728x90

 

 

Windows에서 VMWare를 설치하고 난 이후

CentOS 7 설치하고 Network 인식이 안되어서 ping이 나가지 않는다.

 

하나 하나 해결하는 과정이다.

 

처음에는 NAT 로 설정되어 있어서 Bridge 모드로 변경하는 과정이다.

 

네트워크 기본 설정을 하고 나면 아래의 과정으로 다음을 진행하면 된다.

yum -y update 를 했더니...

Cannot find a valid baseurl for repo: base/7/x86_64

와 같은 메시지가 출력된다.

#############################################
######### CentOS 7 버전 확인 ##################
#############################################
cat /etc/redhat-release
 
# yum repolist 를 했을 때 반응이 없을 때
1. 네트워크 설정이 잘못된 것은 없는지 확인한다.
2. DNS 설정 부분을 확인한다.
3. yum repolist 를 해볼 때 에러가 발생하는지 확인한다.
 
 
# 네트워크 설정
# 자동완성 기능을 이용하여 네트워크 초기 설정된 파일명을 찾는다.
# IP주소를 고정으로 하기 위한 설정이다.
vi /etc/sysconfig/network-scripts/ifcfg-en 
까지 입력하고 TAB을 누르면 자동으로 파일이 찾아진다.
 
BOOTPROTO=none
ONBOOT=yes
IPADDR=192.168.1.20
PREFIX=24
GATEWAY=192.168.1.100
DNS1=168.126.63.1
DNS2=168.126.63.2

# 저장하고 빠져나온다.
service network restart
 
# DNS 설정
vi /etc/resolv.conf
nameserver 168.126.63.1
nameserver 168.126.63.2
nameserver 8.8.8.8
 
 
# yum repository 에러 해결
# 기존 repo 백업 처리
mkdir /etc/yum.repos.d/repo_bk 
mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/repo_bk/ 
ls /etc/yum.repos.d/repo_bk/
 
# 새로운 Base Repo 파일 생성
 
vi /etc/yum.repos.d/CentOS-Base.repo
 
[base]
name=CentOS-$releasever - Base
baseurl=http://mirror.kakao.com/centos/$releasever/os/$basearch/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
 
#released updates
[updates]
name=CentOS-$releasever - Updates
# kakao
baseurl=http://mirror.kakao.com/centos/$releasever/updates/$basearch
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
 
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
baseurl=http://centos.mirror.cdnetworks.com/$releasever/extras/$basearch
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
 
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
baseurl=http://centos.mirror.cdnetworks.com/$releasever/centosplus/$basearch
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
 
#contrib - packages by Centos Users
[contrib]
name=CentOS-$releasever - Contrib
baseurl=http://centos.mirror.cdnetworks.com/$releasever/contrib/$basearch
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
 
 
# 변경된 repo 로 적용한다.
# yum 캐시 정리하고 최신 정보를 가져온다.
yum clean all
 
# 현재 활성화된 repo 확인
yum repolist
 
#######################################################################
#CentOS update
yum -y update
 
#######################################################################
### 시간 동기화
yum -y install rdate
 
crontab -e
00 00  * * * /usr/bin/rdate -s time.bora.net && /sbin/clock -w
 
# 크론탭 재시작
service crond restart
 
#######################################################################
# 방화벽 설정
yum -y install firewalld
 
# 방화벽 데몬 시작
systemctl start firewalld
 
# 서버 부팅 시 firewalld 데몬 자동 시작 설정
systemctl enable firewalld
 
firewall-cmd --permanent --add-service=http 
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-service=mysql
firewall-cmd --permanent --zone=public --add-port=3306/tcp
 
firewall-cmd --permanent --zone=public --add-port=8000/tcp
firewall-cmd --reload
firewall-cmd --list-all
 
####################################################################
# mc 설치
yum -y install mc
 
# 열린포트 확인
yum -y install net-tools
netstat -nltp
 

 

위 스크립트 파일을 첨부

CentOS7_inital_setting.txt
0.00MB

728x90
블로그 이미지

Link2Me

,