문제

Flutter run --release 나 Xcode 에서 릴리즈 모드로 실행시에도 정상 실행이 되는데 배포만 하면 스플래시 화면에서 하얀색(white, blank) 화면이 나오며 정상 작동이 안되는 경우.

 

해결 방법

나에게 적용된 해결 방법

: 파이어베이스를 사용 안하더라도 만약 애드몹을 사용하고 있다면 파이어베이스 해당 프로젝트 추가 후 설정하고난 후 flutter build ios --release 후 다시 xcode 에 들어가서 Archive 파일을 만든 후 배포

- 그냥 xcode 에 바로 들어가서 Archive 파일을 만들고 배포하는게 아닌 그 전에 flutter build ios --release 후에 하는게 중요하다.

- 애드몹과 파이어베이스의 의존성이 chatgpt나 stackoverflow에서 없다고 하는데 프로젝트가 파이어베이스에 등록되고 프로젝트에 설정을 하지 않으면 안되네요 ㅋㅋ

 

다른 해결 방법.

1. Signing & Capabilities 확인.

2. 실제 기기의 testflight 업데이트 하기.

3. testflight 에서 테스트할 앱을 삭제 후 가장 최신 버전 다운로드 하기.

4. flutter upgrade 후에 다시 배포 하기.

5. pod update 하기.

6. cocoapod 최신 버전으로 업데이트

fail2ban

무차별 비밀번호 대입을 통해 로그인을 시도하는 프로그램 및 해커들로부터 서버를 보호해준다.

똑같은 IP로 n번 로그인 실패를 했을 경우 정해진 시간동안 접속이 불가능하게 설정도 가능하다.

 

보통 SSH에 많이 적용하고 클라우드 상에서 fail2ban을 사용해서 접속을 막는 방법도 많이 사용한다.

 

왜 사용할까?

journalctl -f

해당 명령어를 통해 우리의 서버에 침투중인 상황을 실시간으로 볼 수 있다. 계속 로그가 올라오는게 침입 시도이다.

ctrl + c를 활용하여 빠져나올 수 있다.

 

설치 방법

sudo apt install fail2ban

설치와 동시에 시작되어 방어를 해준다.

 

설정 방법

sudo vi /etc/fail2ban/jail.local

이란 파일을 만든 뒤 내용을 작성하여 적용해 줘야한다.

 

형식 

[DEFAULT]

ignoreip=192.168.0.0/24

bantime=100000

maxretry=3

findtime=100000

 

[sshd]

enabled = true

port=22

filter=sshd

logpath=/var/log/auth.log

 

# (선택) 메일 알림 기능

destemail = 사용자 이메일 ex) user@naver.com

sender = fail2ban@my-server.com

mta = sendmail

action = %(action_mwl)s

 

[DEFAULT] : fail2ban에 지정할 모든 서비스에 대한 설정

ignoreip : 설정을 적용하지 않을 IP 리스트. 보통 내부에서의 접속들은 적용하지 않는다.

bantime : 이상 접속을 감지한 경우 접속을 불가능하게 할 초 단위.

maxretry : 허용 접속 가능한 횟수.

findtime : 이상 접속의 횟수를 총괄 낼 초 단위 시간

[sshd] : ssh 접속 서비스에 대한 설정.

enable : 동작 여부를 나타낸다

port : 감지할 포트. 여러 포트를 사용할 경우 ex) port=22,23,24

filter : 이상 동작이라고 판단할 문자열. 정규식 사용 가능.

logpath : 필터링 할 전체 문자열 파일.

 

형식 전체 해석 : logpath에서 filter 항목을 찾아 findtime 시간 동안 maxretry 횟수 만큼 접속을 시도한 IP를 batime 만큼 차단한다.

 

작성 끝난 후 service fail2ban restart

 

현재 차단 현황 보는 방법과 풀어주기

현황보기 : sudo fail2ban-client status sshd

 

차단 풀어주기 : sudo fail2ban-client set sshd unbanip ip주소

변경 이유는?

인터넷에 서버를 공개하게 되면 즉, 로컬 서버로 서비스를 내게 되면 수많은 악성 프로그램들이 자동으로  로그인을 시도한다. 그러면 서버 부하로 인해 자신의 프로그램을 돌리기 힘들거나 전기세도 많이 나갑니다.
그래서 외부에서 SSH로 서버에 접속 가능한 계정 정보가 노출되더라도 기본 포트(22번)보다 변경된 포트를 사용하는 그나마 보안상 좋기 때문이다.

 

변경 방법
  1. sudo vi /etc/ssh/sshd_config
  2. Port 22 부분은 원하는 포트로 변경 후 저장 ex) Port 2022
  3. service sshd restart 로 ssh 재시작

만약 도메인을 구입하거나 클라우드 서비스를 이용하는게 아닌 로컬 서버인 경우 iptime 공유기 설정 화면에 들어간다

그 후 고급 설정 - NAT/라우터 관리 - 포트포워드 설정 항목에서 새 규칙을 추가한다.

ex)

규칙 이름 : 서버_ssh

내부 IP : 서버 주소(IP)

프로토콜 : TCP

외부 포트 : 새로 변경한 포트 번호 ~ 새로 변경한 포트 번호

내부 포트 : 새로 변경한 포트 번호 ~ 새로 변경한 포트 번호

 

변경 후 재접속 해봤는데 접속이 안될경우

ufw 방화벽으로 인해 해당 포트가 잠겨 있을 수 있으므로

ufw allow 새로 변경한 포트번호 ex) ufw allow 13212

하고 재접속을 시도하면 된다.

 

외부 접속 기록을 확인하는 방법
  1. 접속 시도 기록 : cat /var/log/auth.log
  2. 로그인 기록 : last

 

  1. 네이버 검색 창에 IP 주소 검색 후 브라우저 창에 검색하여 IP time 로그인 창에 접속하기
  2. 보통 초기 설정으로 아이디와 비밀번호가 admin, admin이기 때문에 입력 후 접속하기
  3. 고급 설정 - 네트워크 관리 - DHCP 서버 설정에서 IP 주소 대여 범위가 예를 들어 192.168.123.2 ~ 192.168.123.233으로 되어 있다고 하면 앞의 IP 주소는 놔두고 뒤의 IP 주소를 192.168.123.199(199는 제 임의의 값입니다 마음대로 설정 가능)로 설정하여 200번 이후는 고정 IP설정이 필요한 기기들을 위해 DHCP 서버가 할당하지 못하도록 설정
  4. NAS, 네트워크 프린터, 포트 포워딩 설정 등 고정 IP가 필요한 기기들을 200번 이후로 설정하면 된다
  5. 설정이 필요한 기기의 IP 주소를 알아낸 후 (예로 리눅스 서버의 ifconfig를 통해 알아낸 IP 주소) DHCP 설정 아래 부분의 사용중인 IP 주소 정보에 해당하는 항목을 클릭 후 수동 주소 입력 부분란에 192.168.123.200 ~ 부터 할당하고 싶은 IP 주소를 입력하여 할당하면 된다. ex) 나의 로컬 서버는 192.168.123.200 를 입력하여 할당. 
  6.  그 옆의 값들은 MAC 주소로 건들지 말 것. 그러면 설정이 필요한 기기가 재부팅 되어 원래라면 계속 IP가 자동 할당 되어 접속에 혼란을 만들었지만 해당 MAC 주소를 기반으로 아까 설정해 놓은 IP 주소(192.168.123.200)으로 고정 IP로 설정되어 접속 혼란을 막을 수 있다.
  7. 5번에서 할당 후 재부팅하여 다시 기기의 IP 주소를 확인해보면 성공적으로 할당 되어 있는 것을 확인 가능
  1. iTerm 실행
  2. 메뉴의 Profiles - Open Profiles - Edit Profiles 클릭
  3. Name에 호스트 이름 적기, Tags(필수 x) 호스트 특징 태그 달기, Title은 Job으로 고정
  4. Command 항목에서 Login Shell을 Command로 변경 후 ssh user_name@ip address 형식으로 적어준 후 닫기(자동 저장)
  5. 그리고 다시 메뉴의 Window - Password Manager 클릭
  6. + 버튼 클릭 후 클릭 하여 Account Name(호스트 이름 추천), User name(유저명), Edit Password를 눌러 Password 부분에    비밀번호 입력
  7. 마지막으로 트리거 설정을 위해 Profiles - Open Profiles -호스트 클릭 후 Edit Profiles 클릭
  8. General, Colors, Text ... Advances에서 Advances 클릭 후 Trigeers에서 Eddit 클릭
  9. + 버튼 클릭 후 클릭하여 Regular Expression에 password로 적고 Action은 Open Password Manager로 변경 Parameters에는 아까 비밀번호 Account Name에 설정 해두었던 것을 클릭 후 마지막으로 Instant 체크 후 Close.
  10. iTerm을 종료 후 다시 키면 자동으로 ssh 접속이 실행되며 창이 나오며 Password Manager에서 비밀번호를 선택 후 Enter Password를 눌러 로그인을 손쉽게 가능하게 한다.

플러터 빌드 시 에러 로그를 봐도 해결하기 어려운 문제일 시 아래의 방법을 사용해보면 좋을 것 같아 작성합니다.

 

가장 먼저 flutter doctor -v 해보는 것을 잊지말것!

 

문제가 뭘까?
  1. 내가 사용하는 플러터 버전, 다트 버전, 패키지, 라이브러리, 플러그인이 마지막으로 업데이트된 버전이 아니다. 
  2. 버전에 관련된 캐시들로 인해 문제가 있는 버전으로 계속 실행되어 에러가 나온다.

 

1번째 해결방법 = 마지막으로 업데이트된 버전이 아니다.

1. 플러터 버전을 바꿔본다.

=> FVM을 사용하여 안전하게 플러터 버전을 바꿔본 후 실행해본다. (언제든지 원래 버전을 변경 가능)

 

2. 다트 버전을 바꿔본다.

 

3. 빌드 시 에러 로그가 나오면 문제가 있는 패키지, 라이브러리, 플러그인 이름의 버전을 바꿔본다.

=> flutter pub upgrade 문제있는 패키지, 라이브러리, 플러그인 이름

 

2번째 해결방법 = 캐시들로 인해 문제가 생길경우

먼저, 플러터 관련 캐시 삭제 후 다시 다운로드 하기

flutter clean
flutter pub cache repair
flutter pub get

여기까지 CLI 실행 후 다시 실행하기 이후에도 안된다면 안드로이드 관련 문제 시, IOS 관련 문제 시로 나뉜다.

 

안드로이드 관련 문제 시 

안드로이드 폴더로 이동 후
// mac os
./gradlew clean

// window os
gradlew.bat clean

그 다음
.grade 라는 숨겨진 폴더 제거

그 후 
다시 flutter 빌드 해보기

 

IOS 관련 문제 시 

Pods 폴더, Podfile, Podfile.lock, .symlink 폴더 들을 혹시 모르니 백업 후 삭제
pod cache clean -all
pod repo update
pod install
그 후 
다시 flutter 빌드 해보기

 

많은 도움이 되셨기를 바랍니다!

FireStore 패키지 사용 시 IOS 빌드 시 Running Xcode build가 몇분이나 계속 보여지고 무한 실행 중인 것처럼 늘어지는 경우가 있다.

 

이 문제를 해결하기 위해 아래에 해당하는 문서를 읽어 조금이라도 단축해보려고 한다.

 

 

GitHub - invertase/firestore-ios-sdk-frameworks: ⚡ Precompiled Firestore iOS SDKs extracted from the Firebase iOS SDK reposito

⚡ Precompiled Firestore iOS SDKs extracted from the Firebase iOS SDK repository release downloads for faster build times. - GitHub - invertase/firestore-ios-sdk-frameworks: ⚡ Precompiled Firestore...

github.com

 

왜 느려질까?

Firestore IOS SDK는 대부분 C++ 코드 약 500k줄에 의존하며 가뜩이나 느리다고 소문난 Xcode로 컴파일하기 때문에 오래걸린다. 참고로 CI 구성 시 더욱 느려진다.

 

해결 방법
pod 'FirebaseFirestore', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', :tag => 'version 입력'

해당 코드 라인을 ios/Podfile을 열고 Runner 블록 내부에 추가하면 된다. 즉, target 'Runner' do 아래 라인에 추가.

네이버 로그인 기능을 추가하고 있는데 

프로젝트 이름/ios/Pods/naveridlogin-sdk-ios/NaverThirdPartyLogin.framework/NaverThirdPartyLogin' for architecture arm64

라는 에러가 나오면 실행 취소되었다. 여러가지 방법을 시도한 후 해결한 방법을 적어보려고 한다.

 

  1. 현재 개발하고 있는 flutter 프로젝트의 ios 폴더로 이동.
  2. Runner.xcworkspace를 Xcode로 실행.
  3. Runner, Pods 중 Pods 클릭.
  4. Build Settings -> All 클릭.
  5. Architectures의 Excluded Architecturese에 arm64를 추가하여 다시 실행해 본다.
안드로이드 (android)

1.   마스터 계정 : 애플과 비슷한 이유. 앱을 전체적으로 확일할 있는 마스터 계정. 또는 기능들을 있는 각각의 계정. (사전출시보고서에 입력)

2.   신고 기능 : 커뮤니티 앱일 경우 신고, 사용자 신고 기능 필요.

3.   이용약관 : 이용약관 사용자 정책에 불쾌감을 주는 콘텐츠와 행동을 정의.

4.   디지털 콘텐츠인데 인앱 결제 대신 PG결제를 붙인 경우 : 게임, 소개팅, 자체 콘텐츠 서비스 등의 경우 개별 콘텐츠 마다 원가가 들어가지 않기 때문에 3-% 인앱 결제 수수료를 받아들일 있다. 만약 수수료 부담이 경우 비지니스 모델과 상품 원가에 대해 적극적으로 소명해서 인앱 결제 대상 제외를 요청하거나 결제 페이지를 밖으로 꺼내야함.

5.   회원 가입 생년월일, 성별 등의 부가정보를 필수로 요구하는 경우 : 정보가 어떻게 쓰이는지 소명해야함. 안되면 선택입력.

6.   스토어 실적 순위가 표시된 이미지 또는 텍스트 사용할 경우.

7.   가격과 홍보 정보가 표시된 이미지 또는 텍스를 사용할 경우.

8.   소셜로그인만 존재할 . 내에서 자체 회원가입 필요. 로그인 안하고도 기능 사용가능하게 만드는 우회 가능.

 

아이폰 (ios)

1.   완성도 : 작동이 안되거나 페이지가 있을 경우

2.   ATT 권한 : 앱스토어 등록 개인정보 수집 설정을 했을 경우 유저에게 관련 권한 팝업을 받거나 개인정보를 수집하지 않는 것으로 앱스토어 등록 내용을 수정해야한다.

3.   애플 로그인 : 애플을 영어로 써야하며, 애플 + 다른 단어 합성어 불가. (만약 아이폰 배포 애플 로그인이 없고 달느 구글 로그인이나, 다른 SNS로그인만 있을 경우에도 리젝사유)

4.   마스터 계정 : 로그인이 필요한 앱일 경우 모든 기능을 살펴볼 있는 마스터 계정 또는 분리될 경우 각각 기능 사용 가능한 테스트 계정 제공.

5.   권한 설명: 사진 카메라에 접근시에 시스템 팝업의 권한에 대한 설명 부족.

ð 계정 인증 커뮤니티 사진 등록과 나은 사용자 경험을 제공하기 위해 필요합니다. 설정에서 이를 구성할 있습니다. 자세하게 설명.

6.   신고 기능 : 커뮤니티는 사용자에게 불쾌감을 있으므로 신고를 위한 기능이 있어야함. ( 신고, 사용자 신고 두개 )

7.   디지털 콘텐츠인데 인앱 결제 대신 PG결제를 붙인 경우 : 게임, 소개팅, 자체 콘텐츠 서비스 등의 경우 개별 콘텐츠 마다 원가가 들어가지 않기 때문에 3-% 인앱 결제 수수료를 받아들일 있다. 만약 수수료 부담이 경우 비지니스 모델과 상품 원가에 대해 적극적으로 소명해서 인앱 결제 대상 제외를 요청하거나 결제 페이지를 밖으로 꺼내야함.

8.   회원 가입 생년월일, 성별 등의 부가정보를 필수로 요구하는 경우 : 정보가 어떻게 쓰이는지 소명해야함. 안되면 선택입력.

9.   푸시 알림 강요 : 푸시 알림은 사용자가 수신을 취소 가능하게 제공해야한다.

10.리워드 증정 금지 : 친구 초대 또는 리뷰 작성 보상을 증정하는 리워드 금지.

11.웹뷰앱 : 웹뷰는 모바일 기능이 앱으로서 기능을 하는지 여부를 묻는다. 손쉬운 통과를 위해서 푸시 알림 넣기, 카메라 기능 넣기 등이 있다.

12.소스상 사용하지 않는 이미지가 있을 경우.

13.국내 본인인증 서비스등을 사용할 경우 : 신규 사용자 등록 프로세스 비디오 등을 만들어놓는게 좋다.

14.음란 컨텐츠에 대한 차단 검수 여부 : 해당 컨텐츠에 대한 필터링 검수 프로세스를 요청할 있음.

15.타사 플랫폼 언급 : 애플 플랫폼 외의 안드로이드, 구글플레이 등과 관련된 문구나 이미지가 포함되면 거절될 있다. 안드로이드가 탑재된 기기의 이미지 사용도 위험.

16. 저작권/상표권 침해 : 허가받지 않은 타사의 상표를 콘텐츠에 포함시키거나 저작권을 위반한 콘텐츠가 포함될 경우 등록 거절 사유가 있다.

17. 소셜로그인만 존재할 . 내에서 자체 회원가입 필요. 로그인 안하고도 기능 사용가능하게 만드는 우회 가능.

class Node {
	constructor(value) {
		this.value = value;
		this.next = null;
	}
}

class Deque {
	constructor() {
		this.head = null;
		this.tail = null;
		this.size = 0;
	}
	
	unshift(value) {
		if (this.head === null) {
			this.head = new Node(value);
			this.tail = this.head;
			this.size++;
			return;
		}
		
		let newNode = new Node(value);
		let current = this.head;
		
		this.size++;
		this.head = newNode;
		this.head.next = current;
	}
	
	shift() {
		if (this.head === null) return;
		if (this.head.next === null) {
			this.head = null;
			this.tail = null;
			this.size--;
			return;
		}
		
		this.size--;
		this.head = this.head.next;
	}
	
	push(value) {
		if (this.head === null) {
			this.head = new Node(value);
			this.tail = this.head;
			this.size++;
			return;
		}
		
		this.size++;
		this.tail.next = new Node(value);
		this.tail = this.tail.next;
	}
	
		pop() {
		if (this.head === null) return;
		if (this.head.next === null) {
			this.head = null;
			this.tail = null;
			this.size--;
			return;
		}
		
		let current = this.head;
		
		while(current.next.next) {
			current = current.next;
		}
		
		this.size--;
		current.next = null;
		this.tail = current;
	}
	
	isEmpty() {
		return this.head === null ? true : false;
	}
	
	get length() {
		return this.size;
	}

	clear() {
		this.head = null;
		this.tail = null;
		this.size = 0;
	}
}

+ Recent posts