원격 데이터베이스에 연결할 때 데이터베이스 서버와 애플리케이션 서버가 동일한 LAN에 있지 않은 경우 전송 중에 데이터를 가로 채거나 변조 할 수 있습니다. 따라서 데이터 전송의 보안을 보장하기 위해 SSL 암호화 된 연결을 사용하는 것이 좋습니다.
<span><span><span class="hljs-variable">$mysqli</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">mysqli</span></span><span>(</span><span><span class="hljs-string">'remote_host'</span></span><span>, </span><span><span class="hljs-string">'username'</span></span><span>, </span><span><span class="hljs-string">'password'</span></span><span>, </span><span><span class="hljs-string">'database'</span></span><span>, </span><span><span class="hljs-number">3306</span></span><span>);
</span><span><span class="hljs-comment">// 설정SSL연결하다</span></span><span>
</span><span><span class="hljs-variable">$mysqli</span></span><span>-></span><span><span class="hljs-title function_ invoke__">ssl_set</span></span><span>(</span><span><span class="hljs-literal">NULL</span></span><span>, </span><span><span class="hljs-literal">NULL</span></span><span>, </span><span><span class="hljs-string">'/path/to/client-cert.pem'</span></span><span>, </span><span><span class="hljs-string">'/path/to/client-key.pem'</span></span><span>, </span><span><span class="hljs-string">'/path/to/ca-cert.pem'</span></span><span>);
</span><span><span class="hljs-variable">$mysqli</span></span><span>-></span><span><span class="hljs-title function_ invoke__">real_connect</span></span><span>(</span><span><span class="hljs-string">'remote_host'</span></span><span>, </span><span><span class="hljs-string">'username'</span></span><span>, </span><span><span class="hljs-string">'password'</span></span><span>, </span><span><span class="hljs-string">'database'</span></span><span>);
</span></span>
SSL 인증서의 구성은 약간의 복잡성을 증가 시키지만, 특히 데이터 트래픽이 많은 시나리오에서 데이터 전송 보안을 크게 향상시킬 수 있습니다.
데이터베이스의 보안은 데이터베이스 루트 계정을 사용하여 원격으로 직접 연결하지 마십시오. 루트 계정은 데이터베이스에 가장 높은 권한이 있습니다. 일단 유출되면 해커는 데이터베이스를 마음대로 작동하여 돌이킬 수없는 손실을 초래할 수 있습니다.
제한된 권한이있는 데이터베이스 사용자를 생성하고 특정 데이터베이스 또는 테이블 만 액세스하는 것과 같은 필요한 권한 만 제공하십시오. 다음은 사용자를 생성하고 권한을 부여하는 예입니다.
<span><span><span class="hljs-keyword">CREATE</span></span><span> </span><span><span class="hljs-keyword">USER</span></span><span> </span><span><span class="hljs-string">'web_user'</span></span><span>@</span><span><span class="hljs-string">'%'</span></span><span> IDENTIFIED </span><span><span class="hljs-keyword">BY</span></span><span> </span><span><span class="hljs-string">'secure_password'</span></span><span>;
</span><span><span class="hljs-keyword">GRANT</span></span><span> </span><span><span class="hljs-keyword">SELECT</span></span><span>, </span><span><span class="hljs-keyword">INSERT</span></span><span>, </span><span><span class="hljs-keyword">UPDATE</span></span><span> </span><span><span class="hljs-keyword">ON</span></span><span> your_database.</span><span><span class="hljs-operator">*</span></span><span> </span><span><span class="hljs-keyword">TO</span></span><span> </span><span><span class="hljs-string">'web_user'</span></span><span>@</span><span><span class="hljs-string">'%'</span></span><span>;
</span></span>
그런 다음 데이터베이스 연결을 위해 PHP에서 해당 사용자를 사용하십시오.
<span><span><span class="hljs-variable">$mysqli</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">mysqli</span></span><span>(</span><span><span class="hljs-string">'remote_host'</span></span><span>, </span><span><span class="hljs-string">'web_user'</span></span><span>, </span><span><span class="hljs-string">'secure_password'</span></span><span>, </span><span><span class="hljs-string">'database'</span></span><span>);
</span></span>
진술을 준비하면 SQL 주입 공격을 효과적으로 방지 할 수있을뿐만 아니라 특히 동일한 쿼리 문이 여러 번 실행될 때 데이터베이스 쿼리의 성능을 향상시킬 수 있습니다. MySQL은 준비 문을 구현하기위한 강력한 지원을 제공합니다.
<span><span><span class="hljs-variable">$stmt</span></span><span> = </span><span><span class="hljs-variable">$mysqli</span></span><span>-></span><span><span class="hljs-title function_ invoke__">prepare</span></span><span>(</span><span><span class="hljs-string">"SELECT * FROM users WHERE email = ?"</span></span><span>);
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">bind_param</span></span><span>(</span><span><span class="hljs-string">"s"</span></span><span>, </span><span><span class="hljs-variable">$email</span></span><span>); </span><span><span class="hljs-comment">// "s"문자열 유형을 나타냅니다</span></span><span>
</span><span><span class="hljs-variable">$email</span></span><span> = </span><span><span class="hljs-string">'[email protected]'</span></span><span>;
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">execute</span></span><span>();
</span><span><span class="hljs-variable">$result</span></span><span> = </span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">get_result</span></span><span>();
</span></span>
준비 문을 사용하여 사용자의 컨텐츠 입력은 SQL 문에 직접 접합되지 않으므로 SQL 주입의 위험을 효과적으로 피합니다.
동시성이 높은 경우 데이터베이스 연결의 빈번한 생성 및 파괴는 응용 프로그램의 성능에 큰 영향을 줄 수 있습니다. 데이터베이스 연결의 효율성을 향상 시키려면 데이터베이스 연결 풀을 사용하는 것이 좋습니다. MySQLI는 연결 풀링 기능 자체를 제공하지 않지만 PHP-FPM 및 MySQLND 드라이버와 같은 일부 도구 또는 프레임 워크 또는 외부 연결 풀링 서비스 (예 : proxySQL)를 사용하여 구현할 수 있습니다.
연결 풀을 통해 응용 프로그램은 기존 연결을 재사용하여 빈번한 연결 설정의 오버 헤드를 줄일 수 있습니다.
데이터베이스의 보안을 높이려면 데이터베이스 서버에서 방화벽을 구성하여 특정 IP의 연결 만 허용 할 수 있습니다. 특히 생산 환경에서 IP 주소가 데이터베이스에 연결하도록하지 마십시오.
MySQL에서 다음 SQL 명령을 통해 IP 액세스를 제한 할 수 있습니다.
<span><span><span class="hljs-keyword">GRANT</span></span><span> </span><span><span class="hljs-keyword">ALL</span></span><span> PRIVILEGES </span><span><span class="hljs-keyword">ON</span></span><span> your_database.</span><span><span class="hljs-operator">*</span></span><span> </span><span><span class="hljs-keyword">TO</span></span><span> </span><span><span class="hljs-string">'web_user'</span></span><span>@</span><span><span class="hljs-string">'192.168.1.100'</span></span><span>;
</span></span>
Web_User가 지정된 IP 주소에서만 연결해야합니다.
대기 시간이 높거나 불안정한 네트워크 환경에서는 데이터베이스에 연결할 때 시간 초과 문제가 발생할 수 있습니다. 합리적인 시간 초과가 설정되지 않은 경우 연결 요청이 중단되어 응용 프로그램의 응답 시간에 영향을 줄 수 있습니다.
MySQL은 반응이없는 연결을 피하기 위해 연결 시간 초과 설정을 지원합니다.
<span><span><span class="hljs-variable">$mysqli</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">mysqli</span></span><span>();
</span><span><span class="hljs-variable">$mysqli</span></span><span>-></span><span><span class="hljs-title function_ invoke__">options</span></span><span>(MYSQLI_OPT_CONNECT_TIMEOUT, </span><span><span class="hljs-number">5</span></span><span>); </span><span><span class="hljs-comment">// 설정연결하다超时为5두번째</span></span><span>
</span><span><span class="hljs-variable">$mysqli</span></span><span>-></span><span><span class="hljs-title function_ invoke__">real_connect</span></span><span>(</span><span><span class="hljs-string">'remote_host'</span></span><span>, </span><span><span class="hljs-string">'username'</span></span><span>, </span><span><span class="hljs-string">'password'</span></span><span>, </span><span><span class="hljs-string">'database'</span></span><span>);
</span></span>
원격 데이터베이스와 상호 작용할 때 Select *를 사용하여 모든 필드를 쿼리하지 마십시오. 로컬 데이터베이스에 연결하더라도 불필요한 필드를 쿼리하면 대역폭을 낭비 할 수 있으며 원격 데이터베이스의 네트워크 대기 시간이 더 분명합니다. 따라서 불필요한 데이터 전송을 줄이기 위해 쿼리에 필요한 필드를 명확히하는 것이 좋습니다.
<span><span><span class="hljs-variable">$result</span></span><span> = </span><span><span class="hljs-variable">$mysqli</span></span><span>-></span><span><span class="hljs-title function_ invoke__">query</span></span><span>(</span><span><span class="hljs-string">"SELECT id, name FROM users WHERE status = 'active'"</span></span><span>);
</span></span>
애플리케이션이 다량의 데이터 액세스를 처리 해야하는 경우 데이터베이스로드 밸런싱 및 읽기 쓰기 분리 기술 사용을 고려하십시오. 읽기 작업을 쓰기 작업에서 읽고 다른 데이터베이스 인스턴스에 할당함으로써 시스템의 성능 및 가용성을 효과적으로 개선 할 수 있습니다.
예를 들어, 마스터 데이터베이스는 쓰기 작업에 사용되며 슬레이브 데이터베이스는 읽기 작업에 사용됩니다. PHP는 다른 작업에 따라 연결을위한 해당 데이터베이스를 선택할 수 있습니다.
관련 태그:
mysqli